mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
Tie right-to-left evaluation order to LF v2 (#17811)
* Tie right-to-left evaluation order to LF v2 * fix typo
This commit is contained in:
parent
6933514df5
commit
890dee12bf
@ -253,6 +253,18 @@ featureNatTypeErasure = Feature
|
||||
, featureCppFlag = Just "DAML_NAT_TYPE_ERASURE"
|
||||
}
|
||||
|
||||
-- This feature does not impact the compiler, but does control the evaluation
|
||||
-- order integration tests via @SUPPORTS-LF-FEATURE.
|
||||
featureRightToLeftEvaluation :: Feature
|
||||
featureRightToLeftEvaluation = Feature
|
||||
{ featureName = "Right-to-left evaluation order"
|
||||
, featureVersionReq = VersionReq \case
|
||||
V1 -> noMinorVersion
|
||||
V2 -> allV2MinorVersions
|
||||
, featureCppFlag = Just "DAML_RIGHT_TO_LEFT_EVALUATION"
|
||||
}
|
||||
|
||||
|
||||
featureExperimental :: Feature
|
||||
featureExperimental = Feature
|
||||
{ featureName = "Daml Experimental"
|
||||
@ -281,6 +293,7 @@ allFeatures =
|
||||
, featureDynamicExercise
|
||||
, featurePackageUpgrades
|
||||
, featureNatTypeErasure
|
||||
, featureRightToLeftEvaluation
|
||||
]
|
||||
|
||||
-- | A map from feature CPP flags to features.
|
||||
|
@ -8,7 +8,6 @@ module DA.Daml.Options.Types
|
||||
( Options(..)
|
||||
, EnableScenarioService(..)
|
||||
, EnableScenarios(..)
|
||||
, EvaluationOrder(..)
|
||||
, AllowLargeTuples(..)
|
||||
, StudioAutorunAllScenarios(..)
|
||||
, SkipScenarioValidation(..)
|
||||
@ -188,11 +187,6 @@ newtype AllowLargeTuples = AllowLargeTuples { getAllowLargeTuples :: Bool }
|
||||
newtype StudioAutorunAllScenarios = StudioAutorunAllScenarios { getStudioAutorunAllScenarios :: Bool }
|
||||
deriving Show
|
||||
|
||||
data EvaluationOrder
|
||||
= LeftToRight
|
||||
| RightToLeft
|
||||
deriving (Read, Show, Eq)
|
||||
|
||||
damlArtifactDir :: FilePath
|
||||
damlArtifactDir = ".daml"
|
||||
|
||||
|
@ -182,8 +182,6 @@ da_haskell_library(
|
||||
"true" if skip_validation else "false",
|
||||
"--daml-script-v2",
|
||||
"false",
|
||||
"--evaluation-order",
|
||||
"LeftToRight",
|
||||
],
|
||||
data = [
|
||||
":bond-trading",
|
||||
@ -215,52 +213,42 @@ da_haskell_library(
|
||||
)
|
||||
]
|
||||
|
||||
[
|
||||
da_haskell_test(
|
||||
name = "integration{order}-v2dev-script2".format(
|
||||
order = "-r2l" if eval_order == "RightToLeft" else "",
|
||||
),
|
||||
size = "large",
|
||||
srcs = ["src/DA/Test/DamlcIntegrationMain.hs"],
|
||||
args = [
|
||||
"--daml-lf-version",
|
||||
"2.dev", # script2 only supports 2.x
|
||||
"--skip-validation",
|
||||
"false",
|
||||
"--daml-script-v2",
|
||||
"true",
|
||||
"--evaluation-order",
|
||||
eval_order,
|
||||
],
|
||||
data = [
|
||||
":bond-trading",
|
||||
":cant-skip-preprocessor",
|
||||
":daml-test-files",
|
||||
":package-vetting-package-a.dar",
|
||||
":package-vetting-package-b.dar",
|
||||
":query-lf-lib",
|
||||
"//compiler/damlc/pkg-db",
|
||||
"//compiler/damlc/stable-packages",
|
||||
"//compiler/scenario-service/server:scenario_service_jar",
|
||||
"//daml-script/daml3:daml3-script-2.dev.dar",
|
||||
"@jq_dev_env//:jq",
|
||||
ghc_pkg,
|
||||
],
|
||||
hackage_deps = [
|
||||
"base",
|
||||
],
|
||||
main_function = "DA.Test.DamlcIntegrationMain.main",
|
||||
src_strip_prefix = "src",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":integration-lib",
|
||||
],
|
||||
)
|
||||
for eval_order in [
|
||||
"LeftToRight",
|
||||
"RightToLeft",
|
||||
]
|
||||
]
|
||||
da_haskell_test(
|
||||
name = "integration-v2dev-script2",
|
||||
size = "large",
|
||||
srcs = ["src/DA/Test/DamlcIntegrationMain.hs"],
|
||||
args = [
|
||||
"--daml-lf-version",
|
||||
"2.dev", # script2 only supports 2.x
|
||||
"--skip-validation",
|
||||
"false",
|
||||
"--daml-script-v2",
|
||||
"true",
|
||||
],
|
||||
data = [
|
||||
":bond-trading",
|
||||
":cant-skip-preprocessor",
|
||||
":daml-test-files",
|
||||
":package-vetting-package-a.dar",
|
||||
":package-vetting-package-b.dar",
|
||||
":query-lf-lib",
|
||||
"//compiler/damlc/pkg-db",
|
||||
"//compiler/damlc/stable-packages",
|
||||
"//compiler/scenario-service/server:scenario_service_jar",
|
||||
"//daml-script/daml3:daml3-script-2.dev.dar",
|
||||
"@jq_dev_env//:jq",
|
||||
ghc_pkg,
|
||||
],
|
||||
hackage_deps = [
|
||||
"base",
|
||||
],
|
||||
main_function = "DA.Test.DamlcIntegrationMain.main",
|
||||
src_strip_prefix = "src",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":integration-lib",
|
||||
],
|
||||
)
|
||||
|
||||
# Tests for daml-doc
|
||||
da_haskell_test(
|
||||
|
@ -12,9 +12,9 @@
|
||||
|
||||
{-# LANGUAGE ApplicativeDo #-}
|
||||
|
||||
module SemanticsEvalOrder where
|
||||
-- @DOES-NOT-SUPPORT-LF-FEATURE DAML_RIGHT_TO_LEFT_EVALUATION
|
||||
|
||||
-- @EVALUATION-ORDER LeftToRight
|
||||
module SemanticsEvalOrder where
|
||||
|
||||
import Daml.Script
|
||||
import ScriptAssertHelpers
|
||||
|
@ -12,9 +12,9 @@
|
||||
|
||||
{-# LANGUAGE ApplicativeDo #-}
|
||||
|
||||
module SemanticsEvalOrderRightToLeft where
|
||||
-- @SUPPORTS-LF-FEATURE DAML_RIGHT_TO_LEFT_EVALUATION
|
||||
|
||||
-- @EVALUATION-ORDER RightToLeft
|
||||
module SemanticsEvalOrderRightToLeft where
|
||||
|
||||
import Daml.Script
|
||||
import ScriptAssertHelpers
|
||||
|
@ -131,14 +131,6 @@ instance IsOption IsScriptV2Opt where
|
||||
optionName = Tagged "daml-script-v2"
|
||||
optionHelp = Tagged "Use daml script v2 (true|false)"
|
||||
|
||||
newtype EvaluationOrderOpt = EvaluationOrderOpt EvaluationOrder
|
||||
|
||||
instance IsOption EvaluationOrderOpt where
|
||||
defaultValue = EvaluationOrderOpt LeftToRight
|
||||
parseValue = fmap EvaluationOrderOpt . readMaybe
|
||||
optionName = Tagged "evaluation-order"
|
||||
optionHelp = Tagged "Use the specified evaluation order for Daml expressions"
|
||||
|
||||
type ScriptPackageData = (FilePath, [PackageFlag])
|
||||
|
||||
-- | Creates a temp directory with daml script v1 installed, gives the database db path and package flag
|
||||
@ -202,12 +194,11 @@ main = do
|
||||
-- This is a bit hacky, we want the LF version before we hand over to
|
||||
-- tasty. To achieve that we first pass with optparse-applicative ignoring
|
||||
-- everything apart from the LF version.
|
||||
(LfVersionOpt lfVer, SkipValidationOpt _, IsScriptV2Opt isV2, EvaluationOrderOpt evalOrder) <- do
|
||||
let parser = (,,,)
|
||||
(LfVersionOpt lfVer, SkipValidationOpt _, IsScriptV2Opt isV2) <- do
|
||||
let parser = (,,)
|
||||
<$> optionCLParser
|
||||
<*> optionCLParser
|
||||
<*> optionCLParser
|
||||
<*> optionCLParser
|
||||
<* many (strArgument @String mempty)
|
||||
execParser (info parser forwardOptions)
|
||||
|
||||
@ -217,7 +208,7 @@ main = do
|
||||
let scenarioConf = SS.defaultScenarioServiceConfig
|
||||
{ SS.cnfJvmOptions = ["-Xmx200M"]
|
||||
, SS.cnfEvaluationTimeout = Just 3
|
||||
, SS.cnfEvaluationOrder = evalOrder }
|
||||
}
|
||||
|
||||
withDep $ \scriptPackageData ->
|
||||
SS.withScenarioService lfVer scenarioLogger scenarioConf $ \scenarioService -> do
|
||||
@ -236,7 +227,6 @@ main = do
|
||||
[ Option (Proxy @LfVersionOpt)
|
||||
, Option (Proxy @SkipValidationOpt)
|
||||
, Option (Proxy @IsScriptV2Opt)
|
||||
, Option (Proxy @EvaluationOrderOpt)
|
||||
] :
|
||||
defaultIngredients
|
||||
|
||||
@ -334,7 +324,6 @@ getIntegrationTests registerTODO scenarioService (packageDbPath, packageFlags) =
|
||||
tree = askOption $ \(LfVersionOpt version) ->
|
||||
askOption @IsScriptV2Opt $ \isScriptV2Opt ->
|
||||
askOption $ \(SkipValidationOpt skipValidation) ->
|
||||
askOption $ \(EvaluationOrderOpt evalOrder) ->
|
||||
let opts = (defaultOptions (Just version))
|
||||
{ optPackageDbs = [packageDbPath]
|
||||
, optThreads = 0
|
||||
@ -363,7 +352,7 @@ getIntegrationTests registerTODO scenarioService (packageDbPath, packageFlags) =
|
||||
shutdown
|
||||
$ \service ->
|
||||
testGroup ("Tests for Daml-LF " ++ renderPretty version) $
|
||||
map (damlFileTestTree version isScriptV2Opt evalOrder service outdir registerTODO) damlTests
|
||||
map (damlFileTestTree version isScriptV2Opt service outdir registerTODO) damlTests
|
||||
|
||||
pure tree
|
||||
|
||||
@ -415,8 +404,8 @@ testSetup getService outdir path = do
|
||||
, buildLog
|
||||
}
|
||||
|
||||
damlFileTestTree :: LF.Version -> IsScriptV2Opt -> EvaluationOrder -> IO IdeState -> FilePath -> (TODO -> IO ()) -> DamlTestInput -> TestTree
|
||||
damlFileTestTree version (IsScriptV2Opt isScriptV2Opt) evalOrderOpt getService outdir registerTODO input
|
||||
damlFileTestTree :: LF.Version -> IsScriptV2Opt -> IO IdeState -> FilePath -> (TODO -> IO ()) -> DamlTestInput -> TestTree
|
||||
damlFileTestTree version (IsScriptV2Opt isScriptV2Opt) getService outdir registerTODO input
|
||||
| any (ignoreVersion version) anns =
|
||||
singleTest name $ TestCase \_ ->
|
||||
pure (testPassed "") { resultShortDescription = "IGNORE" }
|
||||
@ -466,7 +455,6 @@ damlFileTestTree version (IsScriptV2Opt isScriptV2Opt) evalOrderOpt getService o
|
||||
SupportsFeature featureName -> not (version `satisfies` versionReqForFeaturePartial featureName)
|
||||
DoesNotSupportFeature featureName -> version `satisfies` versionReqForFeaturePartial featureName
|
||||
ScriptV2 -> not isScriptV2Opt
|
||||
EvaluationOrder evalOrder -> evalOrder /= evalOrderOpt
|
||||
_ -> False
|
||||
diff ref new = [POSIX_DIFF, "--strip-trailing-cr", ref, new]
|
||||
|
||||
@ -570,8 +558,6 @@ data Ann
|
||||
| Ledger String FilePath
|
||||
-- ^ I expect the output of running the script named <first argument> to match the golden file <second argument>.
|
||||
-- The path of the golden file is relative to the `.daml` test file.
|
||||
| EvaluationOrder EvaluationOrder
|
||||
-- ^ Only run this test with the given evaluation order.
|
||||
|
||||
readFileAnns :: FilePath -> IO [Ann]
|
||||
readFileAnns file = do
|
||||
@ -592,7 +578,6 @@ readFileAnns file = do
|
||||
("SCRIPT-V2", _) -> Just ScriptV2
|
||||
("TODO",x) -> Just $ Todo x
|
||||
("LEDGER", words -> [script, path]) -> Just $ Ledger script path
|
||||
("EVALUATION-ORDER", x) -> EvaluationOrder <$> readMaybe x
|
||||
_ -> error $ "Can't understand test annotation in " ++ show file ++ ", got " ++ show x
|
||||
f _ = Nothing
|
||||
|
||||
|
@ -44,7 +44,7 @@ import qualified Data.Set as S
|
||||
import qualified Data.Text as T
|
||||
import System.Directory
|
||||
|
||||
import DA.Daml.Options.Types (EnableScenarioService(..), EnableScenarios(..), EvaluationOrder (..))
|
||||
import DA.Daml.Options.Types (EnableScenarioService(..), EnableScenarios(..))
|
||||
import DA.Daml.Project.Config
|
||||
import DA.Daml.Project.Consts
|
||||
import DA.Daml.Project.Types
|
||||
@ -75,7 +75,6 @@ toLowLevelOpts optDamlLfVersion Options{..} =
|
||||
optEvaluationTimeout = fromMaybe 60 $ cnfEvaluationTimeout optScenarioServiceConfig
|
||||
optGrpcMaxMessageSize = cnfGrpcMaxMessageSize optScenarioServiceConfig
|
||||
optJvmOptions = cnfJvmOptions optScenarioServiceConfig
|
||||
optEvaluationOrder = cnfEvaluationOrder optScenarioServiceConfig
|
||||
|
||||
data Handle = Handle
|
||||
{ hLowLevelHandle :: LowLevel.Handle
|
||||
@ -164,7 +163,6 @@ data ScenarioServiceConfig = ScenarioServiceConfig
|
||||
, cnfGrpcTimeout :: Maybe LowLevel.TimeoutSeconds
|
||||
, cnfEvaluationTimeout :: Maybe LowLevel.TimeoutSeconds
|
||||
, cnfJvmOptions :: [String]
|
||||
, cnfEvaluationOrder :: EvaluationOrder
|
||||
} deriving Show
|
||||
|
||||
defaultScenarioServiceConfig :: ScenarioServiceConfig
|
||||
@ -173,7 +171,6 @@ defaultScenarioServiceConfig = ScenarioServiceConfig
|
||||
, cnfGrpcTimeout = Nothing
|
||||
, cnfEvaluationTimeout = Nothing
|
||||
, cnfJvmOptions = []
|
||||
, cnfEvaluationOrder = LeftToRight
|
||||
}
|
||||
|
||||
readScenarioServiceConfig :: IO ScenarioServiceConfig
|
||||
@ -191,7 +188,6 @@ parseScenarioServiceConfig conf = do
|
||||
cnfGrpcTimeout <- queryOpt "grpc-timeout"
|
||||
cnfEvaluationTimeout <- queryOpt "evaluation-timeout"
|
||||
cnfJvmOptions <- fromMaybe [] <$> queryOpt "jvm-options"
|
||||
let cnfEvaluationOrder = LeftToRight
|
||||
pure ScenarioServiceConfig {..}
|
||||
where queryOpt opt = do
|
||||
a <- queryProjectConfig ["script-service", opt] conf
|
||||
|
@ -48,7 +48,7 @@ import Control.Exception
|
||||
import Control.Monad
|
||||
import Control.Monad.IO.Class
|
||||
import DA.Daml.LF.Mangling
|
||||
import DA.Daml.Options.Types (EnableScenarios (..), EvaluationOrder (..))
|
||||
import DA.Daml.Options.Types (EnableScenarios (..))
|
||||
import qualified DA.Daml.LF.Proto3.EncodeV1 as EncodeV1
|
||||
import qualified Data.ByteString as BS
|
||||
import qualified Data.ByteString.Lazy as BSL
|
||||
@ -89,7 +89,6 @@ data Options = Options
|
||||
, optLogError :: String -> IO ()
|
||||
, optDamlLfVersion :: LF.Version
|
||||
, optEnableScenarios :: EnableScenarios
|
||||
, optEvaluationOrder :: EvaluationOrder
|
||||
}
|
||||
|
||||
type TimeoutSeconds = Int64
|
||||
@ -229,7 +228,6 @@ withScenarioService opts@Options{..} f = do
|
||||
[ optJvmOptions
|
||||
, ["-jar" , optServerJar]
|
||||
, ["--max-inbound-message-size=" <> show size | Just size <- [optGrpcMaxMessageSize]]
|
||||
, ["--evaluation-order=" <> show optEvaluationOrder]
|
||||
]
|
||||
|
||||
exitExpected <- newIORef False
|
||||
|
@ -16,14 +16,12 @@ import com.daml.lf.archive
|
||||
import com.daml.lf.data.ImmArray
|
||||
import com.daml.lf.data.Ref
|
||||
import com.daml.lf.data.Ref.ModuleName
|
||||
import com.daml.lf.language.LanguageDevConfig.{EvaluationOrder, LeftToRight, RightToLeft}
|
||||
import com.daml.lf.language.LanguageVersion
|
||||
import com.daml.lf.scenario.api.v1.{Map => _, _}
|
||||
import com.daml.logging.LoggingContext
|
||||
import io.grpc.stub.StreamObserver
|
||||
import io.grpc.{Status, StatusRuntimeException}
|
||||
import io.grpc.netty.NettyServerBuilder
|
||||
import scopt.Read
|
||||
|
||||
import java.time.Instant
|
||||
import scala.util.Random
|
||||
@ -35,8 +33,7 @@ import scala.jdk.CollectionConverters._
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
private final case class ScenarioServiceConfig(
|
||||
maxInboundMessageSize: Int,
|
||||
evaluationOrder: EvaluationOrder,
|
||||
maxInboundMessageSize: Int
|
||||
)
|
||||
|
||||
@SuppressWarnings(Array("org.wartremover.warts.NonUnitStatements"))
|
||||
@ -53,26 +50,13 @@ private object ScenarioServiceConfig {
|
||||
.text(
|
||||
s"Optional max inbound message size in bytes. Defaults to ${DefaultMaxInboundMessageSize}."
|
||||
)
|
||||
|
||||
val evaluationOrderRead: Read[EvaluationOrder] = Read.reads {
|
||||
case "LeftToRight" => LeftToRight
|
||||
case "RightToLeft" => RightToLeft
|
||||
case s => throw new IllegalArgumentException(s"$s is not an EvaluationOrder")
|
||||
}
|
||||
opt[EvaluationOrder]("evaluation-order")(evaluationOrderRead)
|
||||
.optional()
|
||||
.action((x, c) => c.copy(evaluationOrder = x))
|
||||
.text(
|
||||
"The evaluation order of expressions: LeftToRight or RightToLeft. Defaults to LeftToRight."
|
||||
)
|
||||
}
|
||||
|
||||
def parse(args: Array[String]): Option[ScenarioServiceConfig] =
|
||||
parser.parse(
|
||||
args,
|
||||
ScenarioServiceConfig(
|
||||
maxInboundMessageSize = DefaultMaxInboundMessageSize,
|
||||
evaluationOrder = LeftToRight,
|
||||
maxInboundMessageSize = DefaultMaxInboundMessageSize
|
||||
),
|
||||
)
|
||||
}
|
||||
@ -92,7 +76,7 @@ object ScenarioServiceMain extends App {
|
||||
val server =
|
||||
NettyServerBuilder
|
||||
.forAddress(new InetSocketAddress(InetAddress.getLoopbackAddress, 0)) // any free port
|
||||
.addService(new ScenarioService(config.evaluationOrder))
|
||||
.addService(new ScenarioService())
|
||||
.maxInboundMessageSize(config.maxInboundMessageSize)
|
||||
.build
|
||||
server.start()
|
||||
@ -190,9 +174,7 @@ object ScriptStream {
|
||||
}
|
||||
|
||||
@SuppressWarnings(Array("org.wartremover.warts.NonUnitStatements"))
|
||||
class ScenarioService(
|
||||
evaluationOrder: EvaluationOrder
|
||||
)(implicit
|
||||
class ScenarioService(implicit
|
||||
ec: ExecutionContext,
|
||||
esf: ExecutionSequencerFactory,
|
||||
mat: Materializer,
|
||||
@ -362,7 +344,7 @@ class ScenarioService(
|
||||
majorVersion,
|
||||
LanguageVersion.Minor(req.getLfMinor),
|
||||
)
|
||||
val ctx = Context.newContext(lfVersion, req.getEvaluationTimeout.seconds, evaluationOrder)
|
||||
val ctx = Context.newContext(lfVersion, req.getEvaluationTimeout.seconds)
|
||||
contexts += (ctx.contextId -> ctx)
|
||||
val response = NewContextResponse.newBuilder.setContextId(ctx.contextId).build
|
||||
respObs.onNext(response)
|
||||
@ -480,5 +462,4 @@ class ScenarioService(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import com.daml.lf.speedy.SExpr.{LfDefRef, SDefinitionRef}
|
||||
import com.daml.lf.validation.Validation
|
||||
import com.google.protobuf.ByteString
|
||||
import com.daml.lf.engine.script.{Runner, Script}
|
||||
import com.daml.lf.language.LanguageDevConfig.EvaluationOrder
|
||||
import com.daml.logging.LoggingContext
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@ -37,17 +36,16 @@ object Context {
|
||||
|
||||
private val contextCounter = new AtomicLong()
|
||||
|
||||
def newContext(lfVerion: LanguageVersion, timeout: Duration, evaluationOrder: EvaluationOrder)(
|
||||
implicit loggingContext: LoggingContext
|
||||
def newContext(lfVerion: LanguageVersion, timeout: Duration)(implicit
|
||||
loggingContext: LoggingContext
|
||||
): Context =
|
||||
new Context(contextCounter.incrementAndGet(), lfVerion, timeout, evaluationOrder)
|
||||
new Context(contextCounter.incrementAndGet(), lfVerion, timeout)
|
||||
}
|
||||
|
||||
class Context(
|
||||
val contextId: Context.ContextId,
|
||||
languageVersion: LanguageVersion,
|
||||
timeout: Duration,
|
||||
evaluationOrder: EvaluationOrder,
|
||||
)(implicit
|
||||
loggingContext: LoggingContext
|
||||
) {
|
||||
@ -61,7 +59,6 @@ class Context(
|
||||
packageValidation = Compiler.FullPackageValidation,
|
||||
profiling = Compiler.NoProfile,
|
||||
stacktracing = Compiler.FullStackTrace,
|
||||
evaluationOrder = evaluationOrder,
|
||||
)
|
||||
|
||||
/** The package identifier to use for modules added to the context.
|
||||
@ -81,7 +78,7 @@ class Context(
|
||||
def loadedPackages(): Iterable[PackageId] = extSignatures.keys
|
||||
|
||||
def cloneContext(): Context = synchronized {
|
||||
val newCtx = Context.newContext(languageVersion, timeout, evaluationOrder)
|
||||
val newCtx = Context.newContext(languageVersion, timeout)
|
||||
newCtx.extSignatures = extSignatures
|
||||
newCtx.extDefns = extDefns
|
||||
newCtx.modules = modules
|
||||
|
@ -4,7 +4,6 @@
|
||||
package com.daml.lf
|
||||
package engine
|
||||
|
||||
import com.daml.lf.language.LanguageDevConfig.{EvaluationOrder, LeftToRight}
|
||||
import com.daml.lf.speedy.{
|
||||
AuthorizationChecker,
|
||||
DefaultAuthorizationChecker,
|
||||
@ -38,10 +37,6 @@ import com.daml.lf.transaction.ContractKeyUniquenessMode
|
||||
* steps needed to produce a Result.
|
||||
* @param enableContractUpgrading If set this flag a choice that is executed against
|
||||
* a contract may exist in a package different from that of the package.
|
||||
* @param evaluationOrder The order in which applications are evaluated: from left
|
||||
* to right or from right to left. Right-to-left is incompatible with Daml 2.x
|
||||
* but it is faster and allows for simplifications in the interpreter. We're
|
||||
* aiming for right-to-left to be the default in Daml 3.
|
||||
*/
|
||||
final case class EngineConfig(
|
||||
allowedLanguageVersions: VersionRange[language.LanguageVersion],
|
||||
@ -54,35 +49,7 @@ final case class EngineConfig(
|
||||
checkAuthorization: Boolean = true,
|
||||
iterationsBetweenInterruptions: Long = 10000,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
evaluationOrder: EvaluationOrder = LeftToRight,
|
||||
) {
|
||||
// TODO https://github.com/digital-asset/daml/issues/17270
|
||||
// Remove this overloaded constructor once Canton has been updated.
|
||||
def this(
|
||||
allowedLanguageVersions: VersionRange[language.LanguageVersion],
|
||||
packageValidation: Boolean,
|
||||
stackTraceMode: Boolean,
|
||||
profileDir: Option[Path],
|
||||
contractKeyUniqueness: ContractKeyUniquenessMode,
|
||||
requireSuffixedGlobalContractId: Boolean,
|
||||
limits: interpretation.Limits,
|
||||
checkAuthorization: Boolean,
|
||||
iterationsBetweenInterruptions: Long,
|
||||
enableContractUpgrading: Boolean,
|
||||
) = this(
|
||||
allowedLanguageVersions,
|
||||
packageValidation,
|
||||
stackTraceMode,
|
||||
profileDir,
|
||||
contractKeyUniqueness,
|
||||
requireSuffixedGlobalContractId,
|
||||
limits,
|
||||
checkAuthorization,
|
||||
iterationsBetweenInterruptions,
|
||||
enableContractUpgrading,
|
||||
LeftToRight,
|
||||
)
|
||||
|
||||
private[lf] def getCompilerConfig: speedy.Compiler.Config =
|
||||
speedy.Compiler.Config(
|
||||
allowedLanguageVersions,
|
||||
@ -102,7 +69,6 @@ final case class EngineConfig(
|
||||
else
|
||||
speedy.Compiler.NoProfile,
|
||||
enableContractUpgrading = enableContractUpgrading,
|
||||
evaluationOrder = evaluationOrder,
|
||||
)
|
||||
|
||||
private[lf] def authorizationChecker: AuthorizationChecker =
|
||||
|
@ -7,7 +7,7 @@ package speedy
|
||||
import com.daml.lf.data.Ref._
|
||||
import com.daml.lf.data.{ImmArray, Ref, Struct, Time}
|
||||
import com.daml.lf.language.Ast._
|
||||
import com.daml.lf.language.LanguageDevConfig.{EvaluationOrder, LeftToRight, RightToLeft}
|
||||
import com.daml.lf.language.LanguageVersionRangeOps.LanguageVersionRange
|
||||
import com.daml.lf.language.{
|
||||
LanguageMajorVersion,
|
||||
LanguageVersion,
|
||||
@ -77,7 +77,6 @@ private[lf] object Compiler {
|
||||
profiling: ProfilingMode,
|
||||
stacktracing: StackTraceMode,
|
||||
enableContractUpgrading: Boolean = false,
|
||||
evaluationOrder: EvaluationOrder = LeftToRight,
|
||||
)
|
||||
|
||||
object Config {
|
||||
@ -365,7 +364,7 @@ private[lf] final class Compiler(
|
||||
private[this] def pipeline(sexpr: s.SExpr): t.SExpr =
|
||||
flattenToAnf(
|
||||
closureConvert(sexpr),
|
||||
evaluationOrder = config.evaluationOrder,
|
||||
evaluationOrder = config.allowedLanguageVersions.majorVersion.evaluationOrder,
|
||||
)
|
||||
|
||||
private[this] def compileModule(
|
||||
@ -470,16 +469,12 @@ private[lf] final class Compiler(
|
||||
val t0 = Time.Timestamp.now()
|
||||
|
||||
pkgInterface.lookupPackage(pkgId) match {
|
||||
case Right(pkg) => {
|
||||
case Right(pkg) =>
|
||||
if (
|
||||
!stablePackageIds.contains(pkgId) && !config.allowedLanguageVersions
|
||||
.contains(pkg.languageVersion)
|
||||
)
|
||||
throw LanguageVersionError(pkgId, pkg.languageVersion, config.allowedLanguageVersions)
|
||||
|
||||
if (config.evaluationOrder == RightToLeft && !pkg.languageVersion.isDevVersion)
|
||||
throw CompilationError("Right-to-left evaluation is only available in dev")
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ package speedy
|
||||
import com.daml.lf.data.FrontStack
|
||||
import com.daml.lf.data.Ref.Party
|
||||
import com.daml.lf.interpretation.Error.FailedAuthorization
|
||||
import com.daml.lf.language.LanguageDevConfig.{EvaluationOrder}
|
||||
import com.daml.lf.language.LanguageMajorVersion
|
||||
import com.daml.lf.ledger.FailedAuthorization.{CreateMissingAuthorization, NoAuthorizers}
|
||||
import com.daml.lf.speedy.SError.SError
|
||||
@ -33,188 +32,180 @@ class ChoiceAuthorityTest(majorLanguageVersion: LanguageMajorVersion)
|
||||
implicit val defaultParserParameters: ParserParameters[this.type] =
|
||||
ParserParameters.defaultFor[this.type](majorLanguageVersion)
|
||||
|
||||
for (evaluationOrder <- EvaluationOrder.valuesFor(majorLanguageVersion)) {
|
||||
val pkgs: PureCompiledPackages = SpeedyTestLib.typeAndCompile(
|
||||
p"""
|
||||
module M {
|
||||
|
||||
evaluationOrder.toString - {
|
||||
record @serializable Goal = { goal: Party } ;
|
||||
template (record : Goal) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [M:Goal {goal} record] (Nil @Party);
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
};
|
||||
|
||||
val pkgs: PureCompiledPackages = SpeedyTestLib.typeAndCompile(
|
||||
p"""
|
||||
module M {
|
||||
record @serializable T = { theSig: Party, theCon: Party, theAut: List Party, theGoal: Party };
|
||||
template (this: T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [M:T {theSig} this] Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
|
||||
record @serializable Goal = { goal: Party } ;
|
||||
template (record : Goal) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [M:Goal {goal} record] (Nil @Party);
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
};
|
||||
choice ChoiceWithExplicitAuthority (self) (u: Unit) : Unit,
|
||||
controllers Cons @Party [M:T {theCon} this] Nil @Party
|
||||
, authorizers M:T {theAut} this
|
||||
to
|
||||
ubind x1: ContractId M:Goal <- create @M:Goal (M:Goal { goal = M:T {theGoal} this })
|
||||
in upure @Unit ();
|
||||
};
|
||||
|
||||
record @serializable T = { theSig: Party, theCon: Party, theAut: List Party, theGoal: Party };
|
||||
template (this: T) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [M:T {theSig} this] Nil @Party;
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
val call : Party -> Party -> List Party -> Party -> Update Unit =
|
||||
\(theSig: Party) ->
|
||||
\(theCon: Party) ->
|
||||
\(theAut: List Party) ->
|
||||
\(theGoal: Party) ->
|
||||
ubind
|
||||
cid : ContractId M:T <- create @M:T (M:T {theSig = theSig, theCon = theCon, theAut = theAut, theGoal = theGoal})
|
||||
in exercise @M:T ChoiceWithExplicitAuthority cid ();
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
choice ChoiceWithExplicitAuthority (self) (u: Unit) : Unit,
|
||||
controllers Cons @Party [M:T {theCon} this] Nil @Party
|
||||
, authorizers M:T {theAut} this
|
||||
to
|
||||
ubind x1: ContractId M:Goal <- create @M:Goal (M:Goal { goal = M:T {theGoal} this })
|
||||
in upure @Unit ();
|
||||
};
|
||||
type Success = (SubmittedTransaction, List[AuthRequest])
|
||||
|
||||
val call : Party -> Party -> List Party -> Party -> Update Unit =
|
||||
\(theSig: Party) ->
|
||||
\(theCon: Party) ->
|
||||
\(theAut: List Party) ->
|
||||
\(theGoal: Party) ->
|
||||
ubind
|
||||
cid : ContractId M:T <- create @M:T (M:T {theSig = theSig, theCon = theCon, theAut = theAut, theGoal = theGoal})
|
||||
in exercise @M:T ChoiceWithExplicitAuthority cid ();
|
||||
}
|
||||
""",
|
||||
evaluationOrder,
|
||||
)
|
||||
val alice = Party.assertFromString("Alice")
|
||||
val bob = Party.assertFromString("Bob")
|
||||
val charlie = Party.assertFromString("Charlie")
|
||||
|
||||
type Success = (SubmittedTransaction, List[AuthRequest])
|
||||
// In all these tests; alice is the template signatory; bob is the choice controller
|
||||
val theSig: Party = alice
|
||||
val theCon: Party = bob
|
||||
|
||||
val alice = Party.assertFromString("Alice")
|
||||
val bob = Party.assertFromString("Bob")
|
||||
val charlie = Party.assertFromString("Charlie")
|
||||
def makeSetPartyValue(set: Set[Party]): SValue = {
|
||||
SList(FrontStack(set.toList.map(SParty(_)): _*))
|
||||
}
|
||||
|
||||
// In all these tests; alice is the template signatory; bob is the choice controller
|
||||
val theSig: Party = alice
|
||||
val theCon: Party = bob
|
||||
def runExample(
|
||||
theAut: Set[Party], // The set of parties lists in the explicit choice authority decl.
|
||||
theGoal: Party, // The signatory of the created Goal template.
|
||||
): Either[SError, Success] = {
|
||||
import SpeedyTestLib.loggingContext
|
||||
val committers = Set(theSig, theCon)
|
||||
val example = SEApp(
|
||||
pkgs.compiler.unsafeCompile(e"M:call"),
|
||||
Array(
|
||||
SParty(theSig),
|
||||
SParty(theCon),
|
||||
makeSetPartyValue(theAut),
|
||||
SParty(theGoal),
|
||||
),
|
||||
)
|
||||
val machine = Speedy.Machine.fromUpdateSExpr(pkgs, transactionSeed, example, committers)
|
||||
SpeedyTestLib
|
||||
.buildTransactionCollectRequests(machine)
|
||||
.map { case (x, ars, _) => (x, ars) } // ignoring any UpgradeVerificationRequest
|
||||
}
|
||||
|
||||
def makeSetPartyValue(set: Set[Party]): SValue = {
|
||||
SList(FrontStack(set.toList.map(SParty(_)): _*))
|
||||
"Happy" - {
|
||||
|
||||
"restrict authority: {A,B}-->A (need A)" in {
|
||||
val res = runExample(theAut = Set(alice), theGoal = alice)
|
||||
inside(res) { case Right((_, ars)) =>
|
||||
ars shouldBe List()
|
||||
}
|
||||
}
|
||||
|
||||
def runExample(
|
||||
theAut: Set[Party], // The set of parties lists in the explicit choice authority decl.
|
||||
theGoal: Party, // The signatory of the created Goal template.
|
||||
): Either[SError, Success] = {
|
||||
import SpeedyTestLib.loggingContext
|
||||
val committers = Set(theSig, theCon)
|
||||
val example = SEApp(
|
||||
pkgs.compiler.unsafeCompile(e"M:call"),
|
||||
Array(
|
||||
SParty(theSig),
|
||||
SParty(theCon),
|
||||
makeSetPartyValue(theAut),
|
||||
SParty(theGoal),
|
||||
),
|
||||
)
|
||||
val machine = Speedy.Machine.fromUpdateSExpr(pkgs, transactionSeed, example, committers)
|
||||
SpeedyTestLib
|
||||
.buildTransactionCollectRequests(machine)
|
||||
.map { case (x, ars, _) => (x, ars) } // ignoring any UpgradeVerificationRequest
|
||||
"restrict authority: {A,B}-->B (need B)" in {
|
||||
val res = runExample(theAut = Set(bob), theGoal = bob)
|
||||
inside(res) { case Right((_, ars)) =>
|
||||
ars shouldBe List()
|
||||
}
|
||||
}
|
||||
|
||||
"Happy" - {
|
||||
|
||||
"restrict authority: {A,B}-->A (need A)" in {
|
||||
val res = runExample(theAut = Set(alice), theGoal = alice)
|
||||
inside(res) { case Right((_, ars)) =>
|
||||
ars shouldBe List()
|
||||
}
|
||||
}
|
||||
|
||||
"restrict authority: {A,B}-->B (need B)" in {
|
||||
val res = runExample(theAut = Set(bob), theGoal = bob)
|
||||
inside(res) { case Right((_, ars)) =>
|
||||
ars shouldBe List()
|
||||
}
|
||||
}
|
||||
|
||||
"restrict authority: {A,B}-->{A,B} (need A)" in {
|
||||
val res = runExample(theAut = Set(alice, bob), theGoal = alice)
|
||||
inside(res) { case Right((_, ars)) =>
|
||||
ars shouldBe List()
|
||||
}
|
||||
}
|
||||
|
||||
"restrict authority: {A,B}-->{A,B} (need B)" in {
|
||||
val res = runExample(theAut = Set(alice, bob), theGoal = bob)
|
||||
inside(res) { case Right((_, ars)) =>
|
||||
ars shouldBe List()
|
||||
}
|
||||
}
|
||||
|
||||
"change/gain authority {A,B}-->{C} (need C)" in {
|
||||
inside(runExample(theAut = Set(charlie), theGoal = charlie)) { case Right((_, ars)) =>
|
||||
ars shouldBe List(AuthRequest(holding = Set(alice, bob), requesting = Set(charlie)))
|
||||
}
|
||||
}
|
||||
|
||||
"change/gain authority {A,B}-->{A,C} (need A)" in {
|
||||
inside(runExample(theAut = Set(alice, charlie), theGoal = alice)) {
|
||||
case Right((_, ars)) =>
|
||||
ars shouldBe List(AuthRequest(holding = Set(alice, bob), requesting = Set(charlie)))
|
||||
}
|
||||
}
|
||||
|
||||
"change/gain authority {A,B}-->{B,C} (need B)" in {
|
||||
inside(runExample(theAut = Set(bob, charlie), theGoal = bob)) { case Right((_, ars)) =>
|
||||
ars shouldBe List(AuthRequest(holding = Set(alice, bob), requesting = Set(charlie)))
|
||||
}
|
||||
}
|
||||
|
||||
"restrict authority: {A,B}-->{A,B} (need A)" in {
|
||||
val res = runExample(theAut = Set(alice, bob), theGoal = alice)
|
||||
inside(res) { case Right((_, ars)) =>
|
||||
ars shouldBe List()
|
||||
}
|
||||
}
|
||||
|
||||
"Sad" - { // examples which cause Authorization failure
|
||||
"restrict authority: {A,B}-->{A,B} (need B)" in {
|
||||
val res = runExample(theAut = Set(alice, bob), theGoal = bob)
|
||||
inside(res) { case Right((_, ars)) =>
|
||||
ars shouldBe List()
|
||||
}
|
||||
}
|
||||
|
||||
"restrict authority {A,B}-->{} (empty!)" in {
|
||||
inside(runExample(theAut = Set(), theGoal = alice)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case _: NoAuthorizers =>
|
||||
}
|
||||
}
|
||||
"change/gain authority {A,B}-->{C} (need C)" in {
|
||||
inside(runExample(theAut = Set(charlie), theGoal = charlie)) { case Right((_, ars)) =>
|
||||
ars shouldBe List(AuthRequest(holding = Set(alice, bob), requesting = Set(charlie)))
|
||||
}
|
||||
}
|
||||
|
||||
"change/gain authority {A,B}-->{A,C} (need A)" in {
|
||||
inside(runExample(theAut = Set(alice, charlie), theGoal = alice)) { case Right((_, ars)) =>
|
||||
ars shouldBe List(AuthRequest(holding = Set(alice, bob), requesting = Set(charlie)))
|
||||
}
|
||||
}
|
||||
|
||||
"change/gain authority {A,B}-->{B,C} (need B)" in {
|
||||
inside(runExample(theAut = Set(bob, charlie), theGoal = bob)) { case Right((_, ars)) =>
|
||||
ars shouldBe List(AuthRequest(holding = Set(alice, bob), requesting = Set(charlie)))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
"Sad" - { // examples which cause Authorization failure
|
||||
|
||||
"restrict authority {A,B}-->{} (empty!)" in {
|
||||
inside(runExample(theAut = Set(), theGoal = alice)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case _: NoAuthorizers =>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"restrict authority {A,B}-->A (need B)" in {
|
||||
inside(runExample(theAut = Set(alice), theGoal = bob)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case cma: CreateMissingAuthorization =>
|
||||
cma.authorizingParties shouldBe Set(alice)
|
||||
cma.requiredParties shouldBe Set(bob)
|
||||
}
|
||||
}
|
||||
"restrict authority {A,B}-->A (need B)" in {
|
||||
inside(runExample(theAut = Set(alice), theGoal = bob)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case cma: CreateMissingAuthorization =>
|
||||
cma.authorizingParties shouldBe Set(alice)
|
||||
cma.requiredParties shouldBe Set(bob)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"restrict authority {A,B}-->B (need A)" in {
|
||||
inside(runExample(theAut = Set(bob), theGoal = alice)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case cma: CreateMissingAuthorization =>
|
||||
cma.authorizingParties shouldBe Set(bob)
|
||||
cma.requiredParties shouldBe Set(alice)
|
||||
}
|
||||
}
|
||||
"restrict authority {A,B}-->B (need A)" in {
|
||||
inside(runExample(theAut = Set(bob), theGoal = alice)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case cma: CreateMissingAuthorization =>
|
||||
cma.authorizingParties shouldBe Set(bob)
|
||||
cma.requiredParties shouldBe Set(alice)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"restrict authority: {A,B}-->{A,B} (need C)" in {
|
||||
inside(runExample(theAut = Set(alice, bob), theGoal = charlie)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case cma: CreateMissingAuthorization =>
|
||||
cma.authorizingParties shouldBe Set(alice, bob)
|
||||
cma.requiredParties shouldBe Set(charlie)
|
||||
}
|
||||
}
|
||||
"restrict authority: {A,B}-->{A,B} (need C)" in {
|
||||
inside(runExample(theAut = Set(alice, bob), theGoal = charlie)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case cma: CreateMissingAuthorization =>
|
||||
cma.authorizingParties shouldBe Set(alice, bob)
|
||||
cma.requiredParties shouldBe Set(charlie)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"change/gain authority {A,B}-->{C} (need A)" in {
|
||||
inside(runExample(theAut = Set(charlie), theGoal = alice)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case cma: CreateMissingAuthorization =>
|
||||
cma.authorizingParties shouldBe Set(charlie)
|
||||
cma.requiredParties shouldBe Set(alice)
|
||||
}
|
||||
}
|
||||
"change/gain authority {A,B}-->{C} (need A)" in {
|
||||
inside(runExample(theAut = Set(charlie), theGoal = alice)) { case Left(err) =>
|
||||
inside(err) { case SError.SErrorDamlException(FailedAuthorization(_, why)) =>
|
||||
inside(why) { case cma: CreateMissingAuthorization =>
|
||||
cma.authorizingParties shouldBe Set(charlie)
|
||||
cma.requiredParties shouldBe Set(alice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,6 @@ package speedy
|
||||
import com.daml.lf.data.Ref.{IdString, Party}
|
||||
import com.daml.lf.data.{FrontStack, ImmArray, Ref, Struct}
|
||||
import com.daml.lf.language.{Ast, LanguageMajorVersion}
|
||||
import com.daml.lf.language.LanguageDevConfig.EvaluationOrder
|
||||
import com.daml.lf.speedy.SExpr.SEMakeClo
|
||||
import com.daml.lf.speedy.SValue.SToken
|
||||
import com.daml.lf.speedy.Speedy.{CachedKey, ContractInfo}
|
||||
@ -26,17 +25,13 @@ import org.scalatest.matchers.{MatchResult, Matcher}
|
||||
|
||||
/** Shared test data and functions for testing explicit disclosure.
|
||||
*/
|
||||
private[lf] class ExplicitDisclosureLib(
|
||||
majorLanguageVersion: LanguageMajorVersion,
|
||||
evaluationOrder: EvaluationOrder,
|
||||
) {
|
||||
private[lf] class ExplicitDisclosureLib(majorLanguageVersion: LanguageMajorVersion) {
|
||||
|
||||
implicit val defaultParserParameters: ParserParameters[this.type] =
|
||||
ParserParameters.defaultFor[this.type](majorLanguageVersion)
|
||||
|
||||
val testKeyName: String = "test-key"
|
||||
val pkg: PureCompiledPackages = SpeedyTestLib.typeAndCompile(
|
||||
p"""
|
||||
val pkg: PureCompiledPackages = SpeedyTestLib.typeAndCompile(p"""
|
||||
module TestMod {
|
||||
|
||||
record @serializable Key = { label: Text, maintainers: List Party };
|
||||
@ -89,9 +84,7 @@ private[lf] class ExplicitDisclosureLib(
|
||||
None -> Nil @t
|
||||
| Some x -> Cons @t [x] (Nil @t);
|
||||
}
|
||||
""",
|
||||
evaluationOrder,
|
||||
)
|
||||
""")
|
||||
val useSharedKeys: Boolean = Util.sharedKey(defaultParserParameters.languageVersion)
|
||||
val maintainerParty: IdString.Party = Ref.Party.assertFromString("maintainerParty")
|
||||
val ledgerParty: IdString.Party = Ref.Party.assertFromString("ledgerParty")
|
||||
|
@ -6,7 +6,6 @@ package speedy
|
||||
|
||||
import com.daml.lf.data.Ref.Party
|
||||
import com.daml.lf.interpretation.Error.{ContractKeyNotFound, ContractNotActive}
|
||||
import com.daml.lf.language.LanguageDevConfig.EvaluationOrder
|
||||
import com.daml.lf.language.LanguageMajorVersion
|
||||
import com.daml.lf.speedy.SExpr.SEValue
|
||||
import com.daml.lf.value.Value
|
||||
@ -28,188 +27,228 @@ private[lf] class ExplicitDisclosureTest(majorLanguageVersion: LanguageMajorVers
|
||||
with Inside
|
||||
with Matchers {
|
||||
|
||||
for (evaluationOrder <- EvaluationOrder.valuesFor(majorLanguageVersion)) {
|
||||
val explicitDisclosureLib = new ExplicitDisclosureLib(majorLanguageVersion)
|
||||
|
||||
evaluationOrder.toString - {
|
||||
val explicitDisclosureLib = new ExplicitDisclosureLib(majorLanguageVersion, evaluationOrder)
|
||||
import explicitDisclosureLib._
|
||||
import explicitDisclosureLib._
|
||||
|
||||
"disclosed contract behaviour" - {
|
||||
"fetching contracts" - {
|
||||
"test data validation" in {
|
||||
ledgerParty should not be disclosureParty
|
||||
ledgerParty should not be maintainerParty
|
||||
disclosureParty should not be maintainerParty
|
||||
getOwner(ledgerCaveContract.unversioned.arg) shouldBe Some(ledgerParty)
|
||||
inside(disclosedCaveContract) { case (`contractId`, contract) =>
|
||||
getOwner(contract.arg) shouldBe Some(disclosureParty)
|
||||
}
|
||||
"disclosed contract behaviour" - {
|
||||
"fetching contracts" - {
|
||||
"test data validation" in {
|
||||
ledgerParty should not be disclosureParty
|
||||
ledgerParty should not be maintainerParty
|
||||
disclosureParty should not be maintainerParty
|
||||
getOwner(ledgerCaveContract.unversioned.arg) shouldBe Some(ledgerParty)
|
||||
inside(disclosedCaveContract) { case (`contractId`, contract) =>
|
||||
getOwner(contract.arg) shouldBe Some(disclosureParty)
|
||||
}
|
||||
}
|
||||
|
||||
"ledger queried when contract ID is not disclosed" in {
|
||||
ledgerQueriedWhenContractNotDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
getContract = Map(contractId -> ledgerCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Right(SValue.SAny(_, contract @ SValue.SRecord(`caveTemplateId`, _, _))) =>
|
||||
getOwner(contract.toUnnormalizedValue) shouldBe Some(ledgerParty)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"ledger queried when contract ID is not disclosed" in {
|
||||
ledgerQueriedWhenContractNotDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
getContract = Map(contractId -> ledgerCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Right(SValue.SAny(_, contract @ SValue.SRecord(`caveTemplateId`, _, _))) =>
|
||||
getOwner(contract.toUnnormalizedValue) shouldBe Some(ledgerParty)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"disclosure table queried when contract ID is disclosed" - {
|
||||
"contract ID in disclosure table only" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
disclosedCaveContract,
|
||||
disclosures = List(disclosedCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Right(SValue.SAny(_, contract @ SValue.SRecord(`caveTemplateId`, _, _))) =>
|
||||
getOwner(contract.toUnnormalizedValue) shouldBe Some(disclosureParty)
|
||||
}
|
||||
)
|
||||
"disclosure table queried when contract ID is disclosed" - {
|
||||
"contract ID in disclosure table only" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
disclosedCaveContract,
|
||||
disclosures = List(disclosedCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Right(SValue.SAny(_, contract @ SValue.SRecord(`caveTemplateId`, _, _))) =>
|
||||
getOwner(contract.toUnnormalizedValue) shouldBe Some(disclosureParty)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"contract ID in ledger and disclosure table" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
disclosedCaveContract,
|
||||
getContract = Map(contractId -> ledgerCaveContract),
|
||||
disclosures = List(disclosedCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Right(SValue.SAny(_, contract @ SValue.SRecord(`caveTemplateId`, _, _))) =>
|
||||
getOwner(contract.toUnnormalizedValue) shouldBe Some(disclosureParty)
|
||||
}
|
||||
)
|
||||
"contract ID in ledger and disclosure table" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
disclosedCaveContract,
|
||||
getContract = Map(contractId -> ledgerCaveContract),
|
||||
disclosures = List(disclosedCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Right(SValue.SAny(_, contract @ SValue.SRecord(`caveTemplateId`, _, _))) =>
|
||||
getOwner(contract.toUnnormalizedValue) shouldBe Some(disclosureParty)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
"contract IDs that are inactive" - {
|
||||
"ledger query fails when contract ID is not disclosed" in {
|
||||
ledgerQueryFailsWhenContractNotDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
contractId,
|
||||
"TestMod:destroyCave",
|
||||
committers = Set(ledgerParty),
|
||||
getContract = Map(contractId -> ledgerCaveContract),
|
||||
) { result =>
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
ContractNotActive(`contractId`, `caveTemplateId`, _)
|
||||
)
|
||||
) =>
|
||||
succeed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"disclosure table query fails when contract ID is disclosed" - {
|
||||
"contract ID in disclosure table only" in {
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
disclosedCaveContract,
|
||||
contractId,
|
||||
"TestMod:destroyCave",
|
||||
committers = Set(disclosureParty),
|
||||
disclosures = List(disclosedCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
ContractNotActive(`contractId`, `caveTemplateId`, _)
|
||||
)
|
||||
) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"contract ID in ledger and disclosure table" in {
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
disclosedCaveContract,
|
||||
contractId,
|
||||
"TestMod:destroyCave",
|
||||
committers = Set(disclosureParty, ledgerParty),
|
||||
getContract = Map(contractId -> ledgerCaveContract),
|
||||
disclosures = List(disclosedCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
ContractNotActive(`contractId`, `caveTemplateId`, _)
|
||||
)
|
||||
) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
"contract IDs that are inactive" - {
|
||||
"ledger query fails when contract ID is not disclosed" in {
|
||||
ledgerQueryFailsWhenContractNotDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
contractId,
|
||||
"TestMod:destroyCave",
|
||||
committers = Set(ledgerParty),
|
||||
getContract = Map(contractId -> ledgerCaveContract),
|
||||
) { result =>
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
ContractNotActive(`contractId`, `caveTemplateId`, _)
|
||||
)
|
||||
) =>
|
||||
succeed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"fetching contract keys" - {
|
||||
"test data validation" in {
|
||||
ledgerParty should not be disclosureParty
|
||||
ledgerParty should not be maintainerParty
|
||||
disclosureParty should not be maintainerParty
|
||||
ledgerContractId should not be disclosureContractId
|
||||
inside(disclosedHouseContract) { case (`disclosureContractId`, contract) =>
|
||||
getOwner(contract.arg) shouldBe Some(disclosureParty)
|
||||
getMaintainer(contract.arg) shouldBe Some(maintainerParty)
|
||||
}
|
||||
"disclosure table query fails when contract ID is disclosed" - {
|
||||
"contract ID in disclosure table only" in {
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
disclosedCaveContract,
|
||||
contractId,
|
||||
"TestMod:destroyCave",
|
||||
committers = Set(disclosureParty),
|
||||
disclosures = List(disclosedCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
ContractNotActive(`contractId`, `caveTemplateId`, _)
|
||||
)
|
||||
) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"ledger queried when contract key is not disclosed" in {
|
||||
ledgerQueriedWhenContractNotDisclosed(
|
||||
"contract ID in ledger and disclosure table" in {
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBFetchAny(None)(SEValue(SContractId(contractId)), SEValue.None),
|
||||
disclosedCaveContract,
|
||||
contractId,
|
||||
"TestMod:destroyCave",
|
||||
committers = Set(disclosureParty, ledgerParty),
|
||||
getContract = Map(contractId -> ledgerCaveContract),
|
||||
disclosures = List(disclosedCaveContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
ContractNotActive(`contractId`, `caveTemplateId`, _)
|
||||
)
|
||||
) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"fetching contract keys" - {
|
||||
"test data validation" in {
|
||||
ledgerParty should not be disclosureParty
|
||||
ledgerParty should not be maintainerParty
|
||||
disclosureParty should not be maintainerParty
|
||||
ledgerContractId should not be disclosureContractId
|
||||
inside(disclosedHouseContract) { case (`disclosureContractId`, contract) =>
|
||||
getOwner(contract.arg) shouldBe Some(disclosureParty)
|
||||
getMaintainer(contract.arg) shouldBe Some(maintainerParty)
|
||||
}
|
||||
}
|
||||
|
||||
"ledger queried when contract key is not disclosed" in {
|
||||
ledgerQueriedWhenContractNotDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
committers = Set(ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
)(_ shouldBe Right(SValue.SContractId(ledgerContractId)))
|
||||
}
|
||||
|
||||
"disclosure table queried when contract key is disclosed" - {
|
||||
"contract key in disclosure table only" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
committers = Set(disclosureParty),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(_ shouldBe Right(SValue.SContractId(disclosureContractId)))
|
||||
}
|
||||
|
||||
"contract key in ledger and disclosure table" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
committers = Set(disclosureParty, ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(_ shouldBe Right(SValue.SContractId(disclosureContractId)))
|
||||
}
|
||||
}
|
||||
|
||||
"disclosed contract keys that are inactive" - {
|
||||
"ledger query fails when contract key is not disclosed" in {
|
||||
ledgerQueryFailsWhenContractNotDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
ledgerContractId,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Left(SError.SErrorDamlException(ContractKeyNotFound(`contractKey`))) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"disclosure table query fails when contract key is disclosed" - {
|
||||
"contract key in disclosure table only" in {
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
committers = Set(ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
)(_ shouldBe Right(SValue.SContractId(ledgerContractId)))
|
||||
disclosedHouseContract,
|
||||
disclosureContractId,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(disclosureParty, maintainerParty),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Left(SError.SErrorDamlException(ContractKeyNotFound(`contractKey`))) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"disclosure table queried when contract key is disclosed" - {
|
||||
"contract key in disclosure table only" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
"contract key in ledger and disclosure table" in {
|
||||
for (contractIdToBurn <- Set(ledgerContractId, disclosureContractId)) {
|
||||
// Exercising a single contract ID is sufficient to make the key inactive
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
committers = Set(disclosureParty),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(_ shouldBe Right(SValue.SContractId(disclosureContractId)))
|
||||
}
|
||||
|
||||
"contract key in ledger and disclosure table" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
committers = Set(disclosureParty, ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(_ shouldBe Right(SValue.SContractId(disclosureContractId)))
|
||||
}
|
||||
}
|
||||
|
||||
"disclosed contract keys that are inactive" - {
|
||||
"ledger query fails when contract key is not disclosed" in {
|
||||
ledgerQueryFailsWhenContractNotDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
ledgerContractId,
|
||||
contractIdToBurn,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(ledgerParty),
|
||||
committers = Set(disclosureParty, ledgerParty, maintainerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
GlobalKeyWithMaintainers(
|
||||
contractKey,
|
||||
Set(maintainerParty),
|
||||
) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Left(SError.SErrorDamlException(ContractKeyNotFound(`contractKey`))) =>
|
||||
@ -217,268 +256,220 @@ private[lf] class ExplicitDisclosureTest(majorLanguageVersion: LanguageMajorVers
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"disclosure table query fails when contract key is disclosed" - {
|
||||
"contract key in disclosure table only" in {
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
disclosureContractId,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(disclosureParty, maintainerParty),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Left(SError.SErrorDamlException(ContractKeyNotFound(`contractKey`))) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"contract key in ledger and disclosure table" in {
|
||||
for (contractIdToBurn <- Set(ledgerContractId, disclosureContractId)) {
|
||||
// Exercising a single contract ID is sufficient to make the key inactive
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBUFetchKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
contractIdToBurn,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(disclosureParty, ledgerParty, maintainerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(
|
||||
contractKey,
|
||||
Set(maintainerParty),
|
||||
) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(result =>
|
||||
inside(result) {
|
||||
case Left(SError.SErrorDamlException(ContractKeyNotFound(`contractKey`))) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"looking up contract keys" - {
|
||||
"test data validation" in {
|
||||
ledgerParty should not be disclosureParty
|
||||
ledgerParty should not be maintainerParty
|
||||
disclosureParty should not be maintainerParty
|
||||
ledgerContractId should not be disclosureContractId
|
||||
inside(disclosedHouseContract) { case (`disclosureContractId`, contract) =>
|
||||
getOwner(contract.arg) shouldBe Some(disclosureParty)
|
||||
getMaintainer(contract.arg) shouldBe Some(maintainerParty)
|
||||
"looking up contract keys" - {
|
||||
"test data validation" in {
|
||||
ledgerParty should not be disclosureParty
|
||||
ledgerParty should not be maintainerParty
|
||||
disclosureParty should not be maintainerParty
|
||||
ledgerContractId should not be disclosureContractId
|
||||
inside(disclosedHouseContract) { case (`disclosureContractId`, contract) =>
|
||||
getOwner(contract.arg) shouldBe Some(disclosureParty)
|
||||
getMaintainer(contract.arg) shouldBe Some(maintainerParty)
|
||||
}
|
||||
}
|
||||
|
||||
"ledger queried when contract key is not disclosed" in {
|
||||
ledgerQueriedWhenContractNotDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
committers = Set(ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
)(_ shouldBe Right(SValue.SOptional(Some(SValue.SContractId(ledgerContractId)))))
|
||||
}
|
||||
|
||||
"disclosure table queried when contract key is disclosed" - {
|
||||
"contract key in disclosure table only" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
committers = Set(disclosureParty),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(_ shouldBe Right(SValue.SOptional(Some(SValue.SContractId(disclosureContractId)))))
|
||||
}
|
||||
|
||||
"contract key in ledger and disclosure table" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
committers = Set(disclosureParty, ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(_ shouldBe Right(SValue.SOptional(Some(SValue.SContractId(disclosureContractId)))))
|
||||
}
|
||||
}
|
||||
|
||||
"disclosed contract keys that are inactive" - {
|
||||
"ledger query fails when contract key is not disclosed" in {
|
||||
ledgerQueryFailsWhenContractNotDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
ledgerContractId,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
)(result =>
|
||||
inside(result) { case Right(SValue.SOptional(None)) =>
|
||||
succeed
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"ledger queried when contract key is not disclosed" in {
|
||||
ledgerQueriedWhenContractNotDisclosed(
|
||||
"disclosure table query fails when contract key is disclosed" - {
|
||||
"contract key in disclosure table only" in {
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
committers = Set(ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
)(_ shouldBe Right(SValue.SOptional(Some(SValue.SContractId(ledgerContractId)))))
|
||||
disclosedHouseContract,
|
||||
disclosureContractId,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(disclosureParty, maintainerParty),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(result =>
|
||||
inside(result) { case Right(SValue.SOptional(None)) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"disclosure table queried when contract key is disclosed" - {
|
||||
"contract key in disclosure table only" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
"contract key in ledger and disclosure table" in {
|
||||
for (contractIdToBurn <- Set(ledgerContractId, disclosureContractId)) {
|
||||
// Exercising a single contract ID is sufficient to make the key inactive
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
committers = Set(disclosureParty),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(_ shouldBe Right(SValue.SOptional(Some(SValue.SContractId(disclosureContractId)))))
|
||||
}
|
||||
|
||||
"contract key in ledger and disclosure table" in {
|
||||
disclosureTableQueriedWhenContractDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
committers = Set(disclosureParty, ledgerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(_ shouldBe Right(SValue.SOptional(Some(SValue.SContractId(disclosureContractId)))))
|
||||
}
|
||||
}
|
||||
|
||||
"disclosed contract keys that are inactive" - {
|
||||
"ledger query fails when contract key is not disclosed" in {
|
||||
ledgerQueryFailsWhenContractNotDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
ledgerContractId,
|
||||
contractIdToBurn,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(ledgerParty),
|
||||
committers = Set(disclosureParty, ledgerParty, maintainerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(contractKey, Set(maintainerParty)) -> ledgerContractId
|
||||
GlobalKeyWithMaintainers(
|
||||
contractKey,
|
||||
Set(maintainerParty),
|
||||
) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(result =>
|
||||
inside(result) { case Right(SValue.SOptional(None)) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"disclosure table query fails when contract key is disclosed" - {
|
||||
"contract key in disclosure table only" in {
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
disclosureContractId,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(disclosureParty, maintainerParty),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(result =>
|
||||
inside(result) { case Right(SValue.SOptional(None)) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
"contract key in ledger and disclosure table" in {
|
||||
for (contractIdToBurn <- Set(ledgerContractId, disclosureContractId)) {
|
||||
// Exercising a single contract ID is sufficient to make the key inactive
|
||||
disclosureTableQueryFailsWhenContractDisclosed(
|
||||
SBULookupKey(houseTemplateId)(SEValue(contractSStructKey)),
|
||||
disclosedHouseContract,
|
||||
contractIdToBurn,
|
||||
"TestMod:destroyHouse",
|
||||
committers = Set(disclosureParty, ledgerParty, maintainerParty),
|
||||
getKey = Map(
|
||||
GlobalKeyWithMaintainers(
|
||||
contractKey,
|
||||
Set(maintainerParty),
|
||||
) -> ledgerContractId
|
||||
),
|
||||
getContract = Map(ledgerContractId -> ledgerHouseContract),
|
||||
disclosures = List(disclosedHouseContract),
|
||||
)(result =>
|
||||
inside(result) { case Right(SValue.SOptional(None)) =>
|
||||
succeed
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def ledgerQueriedWhenContractNotDisclosed(
|
||||
sexpr: SExpr.SExpr,
|
||||
committers: Set[Party] = Set.empty,
|
||||
disclosures: Iterable[(Value.ContractId, ContractInfo)] = Iterable.empty,
|
||||
getContract: PartialFunction[Value.ContractId, Value.VersionedContractInstance],
|
||||
getKey: PartialFunction[GlobalKeyWithMaintainers, Value.ContractId] =
|
||||
PartialFunction.empty,
|
||||
)(assertResult: Either[SError.SError, SValue] => Assertion): Assertion = {
|
||||
val (result, machine) =
|
||||
evaluateSExpr(
|
||||
sexpr,
|
||||
committers = committers,
|
||||
disclosures = disclosures,
|
||||
getContract = getContract,
|
||||
getKey = getKey,
|
||||
)
|
||||
|
||||
assertResult(result)
|
||||
machine should haveDisclosedContracts()
|
||||
machine should haveInactiveContractIds()
|
||||
}
|
||||
|
||||
def disclosureTableQueriedWhenContractDisclosed(
|
||||
sexpr: SExpr.SExpr,
|
||||
disclosedContract: (Value.ContractId, ContractInfo),
|
||||
committers: Set[Party] = Set.empty,
|
||||
disclosures: Iterable[(Value.ContractId, ContractInfo)],
|
||||
getContract: PartialFunction[Value.ContractId, Value.VersionedContractInstance] =
|
||||
PartialFunction.empty,
|
||||
getKey: PartialFunction[GlobalKeyWithMaintainers, Value.ContractId] =
|
||||
PartialFunction.empty,
|
||||
)(assertResult: Either[SError.SError, SValue] => Assertion): Assertion = {
|
||||
val (result, machine) =
|
||||
evaluateSExpr(
|
||||
sexpr,
|
||||
committers = committers,
|
||||
disclosures = disclosures,
|
||||
getContract = getContract,
|
||||
getKey = getKey,
|
||||
)
|
||||
|
||||
assertResult(result)
|
||||
machine should haveDisclosedContracts(disclosedContract)
|
||||
machine should haveInactiveContractIds()
|
||||
}
|
||||
|
||||
def ledgerQueryFailsWhenContractNotDisclosed(
|
||||
sexpr: SExpr.SExpr,
|
||||
contractId: ContractId,
|
||||
action: String,
|
||||
committers: Set[Party],
|
||||
disclosures: Iterable[(Value.ContractId, ContractInfo)] = Iterable.empty,
|
||||
getContract: PartialFunction[Value.ContractId, Value.VersionedContractInstance],
|
||||
getKey: PartialFunction[GlobalKeyWithMaintainers, Value.ContractId] =
|
||||
PartialFunction.empty,
|
||||
)(assertResult: Either[SError.SError, SValue] => Assertion): Assertion = {
|
||||
val (result, machine) =
|
||||
evaluateSExprWithSetup(
|
||||
e"""\(contractId: ContractId TestMod:House) ->
|
||||
$action contractId
|
||||
""",
|
||||
Array(SContractId(contractId)),
|
||||
)(
|
||||
sexpr,
|
||||
committers = committers,
|
||||
disclosures = disclosures,
|
||||
getContract = getContract,
|
||||
getKey = getKey,
|
||||
)
|
||||
|
||||
assertResult(result)
|
||||
machine should haveDisclosedContracts()
|
||||
machine should haveInactiveContractIds(contractId)
|
||||
}
|
||||
|
||||
def disclosureTableQueryFailsWhenContractDisclosed(
|
||||
sexpr: SExpr.SExpr,
|
||||
disclosedContract: (Value.ContractId, ContractInfo),
|
||||
contractToDestroy: ContractId,
|
||||
action: String,
|
||||
committers: Set[Party],
|
||||
disclosures: Iterable[(Value.ContractId, ContractInfo)],
|
||||
getContract: PartialFunction[Value.ContractId, Value.VersionedContractInstance] =
|
||||
PartialFunction.empty,
|
||||
getKey: PartialFunction[GlobalKeyWithMaintainers, Value.ContractId] =
|
||||
PartialFunction.empty,
|
||||
)(assertResult: Either[SError.SError, SValue] => Assertion): Assertion = {
|
||||
val (result, machine) =
|
||||
evaluateSExprWithSetup(
|
||||
e"""\(contractId: ContractId TestMod:House) ->
|
||||
$action contractId
|
||||
""",
|
||||
Array(SContractId(contractToDestroy)),
|
||||
)(
|
||||
sexpr,
|
||||
committers = committers,
|
||||
disclosures = disclosures,
|
||||
getContract = getContract,
|
||||
getKey = getKey,
|
||||
)
|
||||
|
||||
assertResult(result)
|
||||
machine should haveDisclosedContracts(disclosedContract)
|
||||
machine should haveInactiveContractIds(contractToDestroy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def ledgerQueriedWhenContractNotDisclosed(
|
||||
sexpr: SExpr.SExpr,
|
||||
committers: Set[Party] = Set.empty,
|
||||
disclosures: Iterable[(Value.ContractId, ContractInfo)] = Iterable.empty,
|
||||
getContract: PartialFunction[Value.ContractId, Value.VersionedContractInstance],
|
||||
getKey: PartialFunction[GlobalKeyWithMaintainers, Value.ContractId] = PartialFunction.empty,
|
||||
)(assertResult: Either[SError.SError, SValue] => Assertion): Assertion = {
|
||||
val (result, machine) =
|
||||
evaluateSExpr(
|
||||
sexpr,
|
||||
committers = committers,
|
||||
disclosures = disclosures,
|
||||
getContract = getContract,
|
||||
getKey = getKey,
|
||||
)
|
||||
|
||||
assertResult(result)
|
||||
machine should haveDisclosedContracts()
|
||||
machine should haveInactiveContractIds()
|
||||
}
|
||||
|
||||
def disclosureTableQueriedWhenContractDisclosed(
|
||||
sexpr: SExpr.SExpr,
|
||||
disclosedContract: (Value.ContractId, ContractInfo),
|
||||
committers: Set[Party] = Set.empty,
|
||||
disclosures: Iterable[(Value.ContractId, ContractInfo)],
|
||||
getContract: PartialFunction[Value.ContractId, Value.VersionedContractInstance] =
|
||||
PartialFunction.empty,
|
||||
getKey: PartialFunction[GlobalKeyWithMaintainers, Value.ContractId] = PartialFunction.empty,
|
||||
)(assertResult: Either[SError.SError, SValue] => Assertion): Assertion = {
|
||||
val (result, machine) =
|
||||
evaluateSExpr(
|
||||
sexpr,
|
||||
committers = committers,
|
||||
disclosures = disclosures,
|
||||
getContract = getContract,
|
||||
getKey = getKey,
|
||||
)
|
||||
|
||||
assertResult(result)
|
||||
machine should haveDisclosedContracts(disclosedContract)
|
||||
machine should haveInactiveContractIds()
|
||||
}
|
||||
|
||||
def ledgerQueryFailsWhenContractNotDisclosed(
|
||||
sexpr: SExpr.SExpr,
|
||||
contractId: ContractId,
|
||||
action: String,
|
||||
committers: Set[Party],
|
||||
disclosures: Iterable[(Value.ContractId, ContractInfo)] = Iterable.empty,
|
||||
getContract: PartialFunction[Value.ContractId, Value.VersionedContractInstance],
|
||||
getKey: PartialFunction[GlobalKeyWithMaintainers, Value.ContractId] = PartialFunction.empty,
|
||||
)(assertResult: Either[SError.SError, SValue] => Assertion): Assertion = {
|
||||
val (result, machine) =
|
||||
evaluateSExprWithSetup(
|
||||
e"""\(contractId: ContractId TestMod:House) ->
|
||||
$action contractId
|
||||
""",
|
||||
Array(SContractId(contractId)),
|
||||
)(
|
||||
sexpr,
|
||||
committers = committers,
|
||||
disclosures = disclosures,
|
||||
getContract = getContract,
|
||||
getKey = getKey,
|
||||
)
|
||||
|
||||
assertResult(result)
|
||||
machine should haveDisclosedContracts()
|
||||
machine should haveInactiveContractIds(contractId)
|
||||
}
|
||||
|
||||
def disclosureTableQueryFailsWhenContractDisclosed(
|
||||
sexpr: SExpr.SExpr,
|
||||
disclosedContract: (Value.ContractId, ContractInfo),
|
||||
contractToDestroy: ContractId,
|
||||
action: String,
|
||||
committers: Set[Party],
|
||||
disclosures: Iterable[(Value.ContractId, ContractInfo)],
|
||||
getContract: PartialFunction[Value.ContractId, Value.VersionedContractInstance] =
|
||||
PartialFunction.empty,
|
||||
getKey: PartialFunction[GlobalKeyWithMaintainers, Value.ContractId] = PartialFunction.empty,
|
||||
)(assertResult: Either[SError.SError, SValue] => Assertion): Assertion = {
|
||||
val (result, machine) =
|
||||
evaluateSExprWithSetup(
|
||||
e"""\(contractId: ContractId TestMod:House) ->
|
||||
$action contractId
|
||||
""",
|
||||
Array(SContractId(contractToDestroy)),
|
||||
)(
|
||||
sexpr,
|
||||
committers = committers,
|
||||
disclosures = disclosures,
|
||||
getContract = getContract,
|
||||
getKey = getKey,
|
||||
)
|
||||
|
||||
assertResult(result)
|
||||
machine should haveDisclosedContracts(disclosedContract)
|
||||
machine should haveInactiveContractIds(contractToDestroy)
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ package speedy
|
||||
import com.daml.lf.data.{FrontStack, ImmArray, Ref}
|
||||
import com.daml.lf.interpretation.{Error => IE}
|
||||
import com.daml.lf.language.{Ast, LanguageMajorVersion}
|
||||
import com.daml.lf.language.LanguageDevConfig.EvaluationOrder
|
||||
import com.daml.lf.testing.parser.Implicits.SyntaxHelper
|
||||
import com.daml.lf.testing.parser.ParserParameters
|
||||
import com.daml.lf.transaction.{SubmittedTransaction, TransactionVersion, Versioned}
|
||||
@ -31,451 +30,440 @@ class LimitsSpec(majorLanguageVersion: LanguageMajorVersion)
|
||||
implicit val defaultParserParameters: ParserParameters[this.type] =
|
||||
ParserParameters.defaultFor[this.type](majorLanguageVersion)
|
||||
|
||||
for (evaluationOrder <- EvaluationOrder.valuesFor(majorLanguageVersion)) {
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(p"""
|
||||
module Mod {
|
||||
|
||||
evaluationOrder.toString - {
|
||||
record @serializable T = {
|
||||
signatories: List Party,
|
||||
observers: List Party
|
||||
};
|
||||
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(
|
||||
p"""
|
||||
module Mod {
|
||||
record @serializable NoOpArg = { controllers: List Party, observers: List Party };
|
||||
|
||||
record @serializable T = {
|
||||
signatories: List Party,
|
||||
observers: List Party
|
||||
};
|
||||
val fetches: List (ContractId Mod:T) -> Update (List Mod:T) =
|
||||
\(cids: List (ContractId Mod:T)) ->
|
||||
case cids of
|
||||
Cons h t ->
|
||||
ubind
|
||||
first: Mod:T <- fetch_template @Mod:T h;
|
||||
rest: List Mod:T <- Mod:fetches t
|
||||
in
|
||||
upure @(List Mod:T) Cons @Mod:T [first] rest
|
||||
| Nil ->
|
||||
upure @(List Mod:T) Nil @Mod:T;
|
||||
|
||||
record @serializable NoOpArg = { controllers: List Party, observers: List Party };
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Mod:T {signatories} this;
|
||||
observers Mod:T {observers} this;
|
||||
agreement "Agreement";
|
||||
choice @nonConsuming NoOp (self) (arg: Mod:NoOpArg): Unit,
|
||||
controllers Mod:NoOpArg {controllers} arg,
|
||||
observers Mod:NoOpArg {observers} arg
|
||||
to
|
||||
upure @Unit ();
|
||||
};
|
||||
}
|
||||
""")
|
||||
|
||||
val fetches: List (ContractId Mod:T) -> Update (List Mod:T) =
|
||||
\(cids: List (ContractId Mod:T)) ->
|
||||
case cids of
|
||||
Cons h t ->
|
||||
ubind
|
||||
first: Mod:T <- fetch_template @Mod:T h;
|
||||
rest: List Mod:T <- Mod:fetches t
|
||||
in
|
||||
upure @(List Mod:T) Cons @Mod:T [first] rest
|
||||
| Nil ->
|
||||
upure @(List Mod:T) Nil @Mod:T;
|
||||
def eval(
|
||||
limits: interpretation.Limits,
|
||||
contracts: PartialFunction[Value.ContractId, Versioned[Value.ContractInstance]],
|
||||
committers: Set[Ref.Party],
|
||||
e: Ast.Expr,
|
||||
agrs: SValue*
|
||||
): Either[SError.SError, SubmittedTransaction] =
|
||||
SpeedyTestLib.buildTransaction(
|
||||
machine = Speedy.Machine.fromUpdateSExpr(
|
||||
compiledPackages = pkgs,
|
||||
transactionSeed = txSeed,
|
||||
updateSE = SExpr.SEApp(pkgs.compiler.unsafeCompile(e), agrs.view.toArray),
|
||||
committers = committers,
|
||||
limits = limits,
|
||||
),
|
||||
getContract = contracts,
|
||||
)
|
||||
|
||||
template (this : T) = {
|
||||
precondition True;
|
||||
signatories Mod:T {signatories} this;
|
||||
observers Mod:T {observers} this;
|
||||
agreement "Agreement";
|
||||
choice @nonConsuming NoOp (self) (arg: Mod:NoOpArg): Unit,
|
||||
controllers Mod:NoOpArg {controllers} arg,
|
||||
observers Mod:NoOpArg {observers} arg
|
||||
to
|
||||
upure @Unit ();
|
||||
};
|
||||
}
|
||||
""",
|
||||
evaluationOrder,
|
||||
"Machine" - {
|
||||
|
||||
val committers = (0 to 100).view.map(i => Ref.Party.assertFromString(s"Parties$i")).toSet
|
||||
val limit = 10
|
||||
val testCases =
|
||||
Table(
|
||||
"size" -> "success",
|
||||
1 -> true,
|
||||
limit -> true,
|
||||
limit + 1 -> false,
|
||||
5 * limit -> false,
|
||||
)
|
||||
|
||||
def eval(
|
||||
limits: interpretation.Limits,
|
||||
contracts: PartialFunction[Value.ContractId, Versioned[Value.ContractInstance]],
|
||||
committers: Set[Ref.Party],
|
||||
e: Ast.Expr,
|
||||
agrs: SValue*
|
||||
): Either[SError.SError, SubmittedTransaction] =
|
||||
SpeedyTestLib.buildTransaction(
|
||||
machine = Speedy.Machine.fromUpdateSExpr(
|
||||
compiledPackages = pkgs,
|
||||
transactionSeed = txSeed,
|
||||
updateSE = SExpr.SEApp(pkgs.compiler.unsafeCompile(e), agrs.view.toArray),
|
||||
committers = committers,
|
||||
limits = limits,
|
||||
),
|
||||
getContract = contracts,
|
||||
"refuse to create a contract with too many signatories" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractSignatories = limit)
|
||||
|
||||
val e =
|
||||
e"""\(signatories: List Party) (observers: List Party) ->
|
||||
create @Mod:T Mod:T { signatories = signatories, observers = observers }
|
||||
"""
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (signatories, observers) = committers.splitAt(i)
|
||||
val result =
|
||||
eval(limits, Map.empty, committers, e, asSParties(signatories), asSParties(observers))
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractSignatories(
|
||||
_,
|
||||
templateId,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe signatories
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to fetch a contract with too many signatories" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractSignatories = limit)
|
||||
val e = e"""\(cid: ContractId Mod:T) -> fetch_template @Mod:T cid"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (signatories, observers) = committers.splitAt(i)
|
||||
val contract = mkContract(signatories, observers)
|
||||
val result =
|
||||
eval(limits, Map(aCid -> contract), signatories, e, SValue.SContractId(aCid))
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractSignatories(
|
||||
_,
|
||||
templateId,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe signatories
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to exercise a contract with too many signatories" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractSignatories = limit)
|
||||
val e =
|
||||
e"""\(cid: ContractId Mod:T) (controllers: List Party) ->
|
||||
exercise @Mod:T NoOp cid Mod:NoOpArg {controllers = controllers, observers = Nil @Party }"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (signatories, observers) = committers.splitAt(i)
|
||||
val contract = mkContract(signatories, observers)
|
||||
val result = eval(
|
||||
limits,
|
||||
Map(aCid -> contract),
|
||||
signatories,
|
||||
e,
|
||||
SValue.SContractId(aCid),
|
||||
asSParties(signatories),
|
||||
)
|
||||
|
||||
"Machine" - {
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractSignatories(
|
||||
_,
|
||||
templateId,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe signatories
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val committers = (0 to 100).view.map(i => Ref.Party.assertFromString(s"Parties$i")).toSet
|
||||
val limit = 10
|
||||
val testCases =
|
||||
Table(
|
||||
"size" -> "success",
|
||||
1 -> true,
|
||||
limit -> true,
|
||||
limit + 1 -> false,
|
||||
5 * limit -> false,
|
||||
"refuse to create a contract with too many observers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractObservers = limit)
|
||||
|
||||
val e =
|
||||
e"""\(signatories: List Party) (observers: List Party) ->
|
||||
create @Mod:T Mod:T { signatories = signatories, observers = observers }
|
||||
"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (observers, signatories) = committers.splitAt(i)
|
||||
val result =
|
||||
eval(
|
||||
limits,
|
||||
Map.empty,
|
||||
signatories,
|
||||
e,
|
||||
asSParties(signatories),
|
||||
asSParties(observers),
|
||||
)
|
||||
|
||||
"refuse to create a contract with too many signatories" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractSignatories = limit)
|
||||
|
||||
val e =
|
||||
e"""\(signatories: List Party) (observers: List Party) ->
|
||||
create @Mod:T Mod:T { signatories = signatories, observers = observers }
|
||||
"""
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (signatories, observers) = committers.splitAt(i)
|
||||
val result =
|
||||
eval(limits, Map.empty, committers, e, asSParties(signatories), asSParties(observers))
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractSignatories(
|
||||
_,
|
||||
templateId,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe signatories
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractObservers(_, templateId, _, parties, reportedlimit)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe observers
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to fetch a contract with too many signatories" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractSignatories = limit)
|
||||
val e = e"""\(cid: ContractId Mod:T) -> fetch_template @Mod:T cid"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (signatories, observers) = committers.splitAt(i)
|
||||
val contract = mkContract(signatories, observers)
|
||||
val result =
|
||||
eval(limits, Map(aCid -> contract), signatories, e, SValue.SContractId(aCid))
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractSignatories(
|
||||
_,
|
||||
templateId,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe signatories
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to exercise a contract with too many signatories" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractSignatories = limit)
|
||||
val e =
|
||||
e"""\(cid: ContractId Mod:T) (controllers: List Party) ->
|
||||
exercise @Mod:T NoOp cid Mod:NoOpArg {controllers = controllers, observers = Nil @Party }"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (signatories, observers) = committers.splitAt(i)
|
||||
val contract = mkContract(signatories, observers)
|
||||
val result = eval(
|
||||
limits,
|
||||
Map(aCid -> contract),
|
||||
signatories,
|
||||
e,
|
||||
SValue.SContractId(aCid),
|
||||
asSParties(signatories),
|
||||
)
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractSignatories(
|
||||
_,
|
||||
templateId,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe signatories
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to create a contract with too many observers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractObservers = limit)
|
||||
|
||||
val e =
|
||||
e"""\(signatories: List Party) (observers: List Party) ->
|
||||
create @Mod:T Mod:T { signatories = signatories, observers = observers }
|
||||
"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (observers, signatories) = committers.splitAt(i)
|
||||
val result =
|
||||
eval(
|
||||
limits,
|
||||
Map.empty,
|
||||
signatories,
|
||||
e,
|
||||
asSParties(signatories),
|
||||
asSParties(observers),
|
||||
)
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractObservers(_, templateId, _, parties, reportedlimit)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe observers
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to fetch a contract with too many observers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractObservers = limit)
|
||||
val e = e"""\(cid: ContractId Mod:T) -> fetch_template @Mod:T cid"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (observers, signatories) = committers.splitAt(i)
|
||||
val contract = mkContract(signatories, observers)
|
||||
val result =
|
||||
eval(limits, Map(aCid -> contract), signatories, e, SValue.SContractId(aCid))
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractObservers(_, templateId, _, parties, reportedlimit)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe observers
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to exercise a contract with too many observers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractObservers = limit)
|
||||
val e =
|
||||
e"""\(cid: ContractId Mod:T) (controllers: List Party) ->
|
||||
exercise @Mod:T NoOp cid Mod:NoOpArg {controllers = controllers, observers = Nil @Party }"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (observers, signatories) = committers.splitAt(i)
|
||||
val contract = mkContract(signatories, observers)
|
||||
val result = eval(
|
||||
limits,
|
||||
Map(aCid -> contract),
|
||||
signatories,
|
||||
e,
|
||||
SValue.SContractId(aCid),
|
||||
asSParties(signatories),
|
||||
)
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractObservers(_, templateId, _, parties, reportedlimit)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe observers
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to exercise a choice with too many controllers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(choiceControllers = limit)
|
||||
val e =
|
||||
e"""\(signatories: List Party) (controllers: List Party) ->
|
||||
ubind
|
||||
cid: ContractId Mod:T <- create @Mod:T Mod:T {
|
||||
signatories = signatories,
|
||||
observers = Nil @Party
|
||||
}
|
||||
in exercise @Mod:T NoOp cid Mod:NoOpArg {controllers = controllers, observers = Nil @Party }
|
||||
"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (controllers, signatories) = committers.splitAt(i)
|
||||
val result =
|
||||
eval(
|
||||
limits,
|
||||
Map.empty,
|
||||
committers,
|
||||
e,
|
||||
asSParties(signatories),
|
||||
asSParties(controllers),
|
||||
)
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ChoiceControllers(
|
||||
_,
|
||||
templateId,
|
||||
choiceName,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
choiceName shouldBe "NoOp"
|
||||
parties shouldBe controllers
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: https://github.com/digital-asset/daml/issues/15882
|
||||
// -- Add a similar test for "too many choice authorizers"
|
||||
"refuse to exercise a choice with too many observers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(choiceObservers = limit)
|
||||
val committers = (0 to 99).view.map(i => Ref.Party.assertFromString(s"Party$i")).toSet
|
||||
val e =
|
||||
e"""\(signatories: List Party) (controllers: List Party) (observers: List Party) ->
|
||||
ubind
|
||||
cid: ContractId Mod:T <- create @Mod:T Mod:T {
|
||||
signatories = signatories,
|
||||
observers = Nil @Party
|
||||
}
|
||||
in exercise @Mod:T NoOp cid Mod:NoOpArg {controllers = controllers, observers = observers}
|
||||
"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (observers, signatories) = committers.splitAt(i)
|
||||
val result = eval(
|
||||
limits,
|
||||
Map.empty,
|
||||
committers,
|
||||
e,
|
||||
asSParties(signatories),
|
||||
asSParties(signatories),
|
||||
asSParties(observers),
|
||||
)
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ChoiceObservers(
|
||||
_,
|
||||
templateId,
|
||||
choiceName,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
choiceName shouldBe "NoOp"
|
||||
parties shouldBe observers
|
||||
reportedlimit shouldBe limit
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to build a transaction with too many input contracts" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(transactionInputContracts = limit)
|
||||
|
||||
val signatories = committers.take(1)
|
||||
val contract = mkContract(signatories, Set.empty)
|
||||
val cids =
|
||||
(1 to 99).map(i => Value.ContractId.V1(crypto.Hash.hashPrivateKey(s"contract$i")))
|
||||
val e = e"Mod:fetches"
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val result = eval(limits, _ => contract, committers, e, asSCids(cids.take(i)))
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(IE.Dev.Limit.TransactionInputContracts(reportedlimit)),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
reportedlimit shouldBe limit
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to fetch a contract with too many observers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractObservers = limit)
|
||||
val e = e"""\(cid: ContractId Mod:T) -> fetch_template @Mod:T cid"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (observers, signatories) = committers.splitAt(i)
|
||||
val contract = mkContract(signatories, observers)
|
||||
val result =
|
||||
eval(limits, Map(aCid -> contract), signatories, e, SValue.SContractId(aCid))
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractObservers(_, templateId, _, parties, reportedlimit)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe observers
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to exercise a contract with too many observers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(contractObservers = limit)
|
||||
val e =
|
||||
e"""\(cid: ContractId Mod:T) (controllers: List Party) ->
|
||||
exercise @Mod:T NoOp cid Mod:NoOpArg {controllers = controllers, observers = Nil @Party }"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (observers, signatories) = committers.splitAt(i)
|
||||
val contract = mkContract(signatories, observers)
|
||||
val result = eval(
|
||||
limits,
|
||||
Map(aCid -> contract),
|
||||
signatories,
|
||||
e,
|
||||
SValue.SContractId(aCid),
|
||||
asSParties(signatories),
|
||||
)
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ContractObservers(_, templateId, _, parties, reportedlimit)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
parties shouldBe observers
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to exercise a choice with too many controllers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(choiceControllers = limit)
|
||||
val e =
|
||||
e"""\(signatories: List Party) (controllers: List Party) ->
|
||||
ubind
|
||||
cid: ContractId Mod:T <- create @Mod:T Mod:T {
|
||||
signatories = signatories,
|
||||
observers = Nil @Party
|
||||
}
|
||||
in exercise @Mod:T NoOp cid Mod:NoOpArg {controllers = controllers, observers = Nil @Party }
|
||||
"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (controllers, signatories) = committers.splitAt(i)
|
||||
val result =
|
||||
eval(
|
||||
limits,
|
||||
Map.empty,
|
||||
committers,
|
||||
e,
|
||||
asSParties(signatories),
|
||||
asSParties(controllers),
|
||||
)
|
||||
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ChoiceControllers(
|
||||
_,
|
||||
templateId,
|
||||
choiceName,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
choiceName shouldBe "NoOp"
|
||||
parties shouldBe controllers
|
||||
reportedlimit shouldBe limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: https://github.com/digital-asset/daml/issues/15882
|
||||
// -- Add a similar test for "too many choice authorizers"
|
||||
"refuse to exercise a choice with too many observers" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(choiceObservers = limit)
|
||||
val committers = (0 to 99).view.map(i => Ref.Party.assertFromString(s"Party$i")).toSet
|
||||
val e =
|
||||
e"""\(signatories: List Party) (controllers: List Party) (observers: List Party) ->
|
||||
ubind
|
||||
cid: ContractId Mod:T <- create @Mod:T Mod:T {
|
||||
signatories = signatories,
|
||||
observers = Nil @Party
|
||||
}
|
||||
in exercise @Mod:T NoOp cid Mod:NoOpArg {controllers = controllers, observers = observers}
|
||||
"""
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val (observers, signatories) = committers.splitAt(i)
|
||||
val result = eval(
|
||||
limits,
|
||||
Map.empty,
|
||||
committers,
|
||||
e,
|
||||
asSParties(signatories),
|
||||
asSParties(signatories),
|
||||
asSParties(observers),
|
||||
)
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(
|
||||
IE.Dev.Limit.ChoiceObservers(
|
||||
_,
|
||||
templateId,
|
||||
choiceName,
|
||||
_,
|
||||
parties,
|
||||
reportedlimit,
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
templateId shouldBe T
|
||||
choiceName shouldBe "NoOp"
|
||||
parties shouldBe observers
|
||||
reportedlimit shouldBe limit
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"refuse to build a transaction with too many input contracts" in {
|
||||
val limits = interpretation.Limits.Lenient.copy(transactionInputContracts = limit)
|
||||
|
||||
val signatories = committers.take(1)
|
||||
val contract = mkContract(signatories, Set.empty)
|
||||
val cids =
|
||||
(1 to 99).map(i => Value.ContractId.V1(crypto.Hash.hashPrivateKey(s"contract$i")))
|
||||
val e = e"Mod:fetches"
|
||||
|
||||
forEvery(testCases) { (i, succeed) =>
|
||||
val result = eval(limits, _ => contract, committers, e, asSCids(cids.take(i)))
|
||||
if (succeed)
|
||||
result shouldBe a[Right[_, _]]
|
||||
else
|
||||
inside(result) {
|
||||
case Left(
|
||||
SError.SErrorDamlException(
|
||||
IE.Dev(
|
||||
_,
|
||||
IE.Dev.Limit(IE.Dev.Limit.TransactionInputContracts(reportedlimit)),
|
||||
)
|
||||
)
|
||||
) =>
|
||||
reportedlimit shouldBe limit
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ package speedy
|
||||
import com.daml.lf.data.ImmArray
|
||||
import com.daml.lf.data.Ref.Party
|
||||
import com.daml.lf.language.Ast.Expr
|
||||
import com.daml.lf.language.LanguageDevConfig.EvaluationOrder
|
||||
import com.daml.lf.language.LanguageMajorVersion
|
||||
import com.daml.lf.speedy.SExpr._
|
||||
import com.daml.lf.speedy.SValue._
|
||||
@ -49,173 +48,164 @@ class RollbackTest(majorLanguageVersion: LanguageMajorVersion)
|
||||
.fold(e => fail(Pretty.prettyError(e).render(80)), identity)
|
||||
}
|
||||
|
||||
for (evaluationOrder <- EvaluationOrder.valuesFor(majorLanguageVersion)) {
|
||||
val pkgs: PureCompiledPackages = SpeedyTestLib.typeAndCompile(p"""
|
||||
module M {
|
||||
|
||||
evaluationOrder.toString - {
|
||||
record @serializable MyException = { message: Text } ;
|
||||
exception MyException = {
|
||||
message \(e: M:MyException) -> M:MyException {message} e
|
||||
};
|
||||
|
||||
val pkgs: PureCompiledPackages = SpeedyTestLib.typeAndCompile(
|
||||
p"""
|
||||
module M {
|
||||
record @serializable T1 = { party: Party, info: Int64 } ;
|
||||
template (record : T1) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [M:T1 {party} record] (Nil @Party);
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch1 (self) (i : Unit) : Unit,
|
||||
controllers Cons @Party [M:T1 {party} record] (Nil @Party)
|
||||
to
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = M:T1 {party} record, info = 400 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = M:T1 {party} record, info = 500 }
|
||||
in upure @Unit ();
|
||||
choice Ch2 (self) (i : Unit) : Unit,
|
||||
controllers Cons @Party [M:T1 {party} record] (Nil @Party)
|
||||
to
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = M:T1 {party} record, info = 400 };
|
||||
u: Unit <- throw @(Update Unit) @M:MyException (M:MyException {message = "oops"});
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = M:T1 {party} record, info = 500 }
|
||||
in upure @Unit ();
|
||||
};
|
||||
|
||||
record @serializable MyException = { message: Text } ;
|
||||
exception MyException = {
|
||||
message \(e: M:MyException) -> M:MyException {message} e
|
||||
};
|
||||
val create0 : Party -> Update Unit = \(party: Party) ->
|
||||
upure @Unit ();
|
||||
|
||||
record @serializable T1 = { party: Party, info: Int64 } ;
|
||||
template (record : T1) = {
|
||||
precondition True;
|
||||
signatories Cons @Party [M:T1 {party} record] (Nil @Party);
|
||||
observers Nil @Party;
|
||||
agreement "Agreement";
|
||||
choice Ch1 (self) (i : Unit) : Unit,
|
||||
controllers Cons @Party [M:T1 {party} record] (Nil @Party)
|
||||
to
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = M:T1 {party} record, info = 400 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = M:T1 {party} record, info = 500 }
|
||||
in upure @Unit ();
|
||||
choice Ch2 (self) (i : Unit) : Unit,
|
||||
controllers Cons @Party [M:T1 {party} record] (Nil @Party)
|
||||
to
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = M:T1 {party} record, info = 400 };
|
||||
u: Unit <- throw @(Update Unit) @M:MyException (M:MyException {message = "oops"});
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = M:T1 {party} record, info = 500 }
|
||||
in upure @Unit ();
|
||||
};
|
||||
val create1 : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 }
|
||||
in upure @Unit ();
|
||||
|
||||
val create0 : Party -> Update Unit = \(party: Party) ->
|
||||
upure @Unit ();
|
||||
val create2 : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in upure @Unit ();
|
||||
|
||||
val create1 : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 }
|
||||
in upure @Unit ();
|
||||
val create3 : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 };
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
val create2 : Party -> Update Unit = \(party: Party) ->
|
||||
val create3nested : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
u1: Unit <-
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in upure @Unit ();
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
val create3 : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 };
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
val create3catchNoThrow : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
u1: Unit <-
|
||||
try @Unit
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in upure @Unit ()
|
||||
catch e -> Some @(Update Unit) (upure @Unit ())
|
||||
;
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
val create3nested : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
u1: Unit <-
|
||||
val create3throwAndCatch : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
u1: Unit <-
|
||||
try @Unit
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in throw @(Update Unit) @M:MyException (M:MyException {message = "oops"})
|
||||
catch e -> Some @(Update Unit) (upure @Unit ())
|
||||
;
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
val create3throwAndOuterCatch : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
u1: Unit <-
|
||||
try @Unit
|
||||
try @Unit
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in upure @Unit ();
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
val create3catchNoThrow : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
u1: Unit <-
|
||||
try @Unit
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in upure @Unit ()
|
||||
catch e -> Some @(Update Unit) (upure @Unit ())
|
||||
;
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
val create3throwAndCatch : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
u1: Unit <-
|
||||
try @Unit
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in throw @(Update Unit) @M:MyException (M:MyException {message = "oops"})
|
||||
catch e -> Some @(Update Unit) (upure @Unit ())
|
||||
;
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
val create3throwAndOuterCatch : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
u1: Unit <-
|
||||
try @Unit
|
||||
try @Unit
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in throw @(Update Unit) @M:MyException (M:MyException {message = "oops"})
|
||||
catch e -> None @(Update Unit)
|
||||
catch e -> Some @(Update Unit) (upure @Unit ())
|
||||
;
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
in throw @(Update Unit) @M:MyException (M:MyException {message = "oops"})
|
||||
catch e -> None @(Update Unit)
|
||||
catch e -> Some @(Update Unit) (upure @Unit ())
|
||||
;
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
|
||||
val exer1 : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
val exer1 : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
|
||||
u: Unit <-
|
||||
try @Unit
|
||||
ubind
|
||||
u: Unit <- exercise @M:T1 Ch1 x1 ();
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in upure @Unit ()
|
||||
catch e -> Some @(Update Unit) (upure @Unit ());
|
||||
u: Unit <-
|
||||
try @Unit
|
||||
ubind
|
||||
u: Unit <- exercise @M:T1 Ch1 x1 ();
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in upure @Unit ()
|
||||
catch e -> Some @(Update Unit) (upure @Unit ());
|
||||
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
|
||||
val exer2 : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
val exer2 : Party -> Update Unit = \(party: Party) ->
|
||||
ubind
|
||||
x1: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 100 };
|
||||
|
||||
u: Unit <-
|
||||
try @Unit
|
||||
ubind
|
||||
u: Unit <- exercise @M:T1 Ch2 x1 ();
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in upure @Unit ()
|
||||
catch e -> Some @(Update Unit) (upure @Unit ());
|
||||
u: Unit <-
|
||||
try @Unit
|
||||
ubind
|
||||
u: Unit <- exercise @M:T1 Ch2 x1 ();
|
||||
x2: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 200 }
|
||||
in upure @Unit ()
|
||||
catch e -> Some @(Update Unit) (upure @Unit ());
|
||||
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
x3: ContractId M:T1 <- create @M:T1 M:T1 { party = party, info = 300 }
|
||||
in upure @Unit ();
|
||||
|
||||
}
|
||||
""",
|
||||
evaluationOrder,
|
||||
)
|
||||
}
|
||||
""")
|
||||
|
||||
val testCases = Table[String, List[Tree]](
|
||||
("expression", "expected-number-of-contracts"),
|
||||
("create0", Nil),
|
||||
("create1", List(C(100))),
|
||||
("create2", List(C(100), C(200))),
|
||||
("create3", List(C(100), C(200), C(300))),
|
||||
("create3nested", List(C(100), C(200), C(300))),
|
||||
("create3catchNoThrow", List(C(100), C(200), C(300))),
|
||||
("create3throwAndCatch", List[Tree](R(List(C(100), C(200))), C(300))),
|
||||
("create3throwAndOuterCatch", List[Tree](R(List(C(100), C(200))), C(300))),
|
||||
("exer1", List[Tree](C(100), X(List(C(400), C(500))), C(200), C(300))),
|
||||
("exer2", List[Tree](C(100), R(List(X(List(C(400))))), C(300))),
|
||||
)
|
||||
val testCases = Table[String, List[Tree]](
|
||||
("expression", "expected-number-of-contracts"),
|
||||
("create0", Nil),
|
||||
("create1", List(C(100))),
|
||||
("create2", List(C(100), C(200))),
|
||||
("create3", List(C(100), C(200), C(300))),
|
||||
("create3nested", List(C(100), C(200), C(300))),
|
||||
("create3catchNoThrow", List(C(100), C(200), C(300))),
|
||||
("create3throwAndCatch", List[Tree](R(List(C(100), C(200))), C(300))),
|
||||
("create3throwAndOuterCatch", List[Tree](R(List(C(100), C(200))), C(300))),
|
||||
("exer1", List[Tree](C(100), X(List(C(400), C(500))), C(200), C(300))),
|
||||
("exer2", List[Tree](C(100), R(List(X(List(C(400))))), C(300))),
|
||||
)
|
||||
|
||||
forEvery(testCases) { (exp: String, expected: List[Tree]) =>
|
||||
s"""$exp, contracts expected: $expected """ in {
|
||||
val party = Party.assertFromString("Alice")
|
||||
val tx: SubmittedTransaction = runUpdateExprGetTx(pkgs)(e"M:$exp", party)
|
||||
val ids: List[Tree] = shapeOfTransaction(tx)
|
||||
ids shouldBe expected
|
||||
}
|
||||
}
|
||||
forEvery(testCases) { (exp: String, expected: List[Tree]) =>
|
||||
s"""$exp, contracts expected: $expected """ in {
|
||||
val party = Party.assertFromString("Alice")
|
||||
val tx: SubmittedTransaction = runUpdateExprGetTx(pkgs)(e"M:$exp", party)
|
||||
val ids: List[Tree] = shapeOfTransaction(tx)
|
||||
ids shouldBe expected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,6 @@ import data.Ref.PackageId
|
||||
import data.Time
|
||||
import SResult._
|
||||
import com.daml.lf.data.Ref.Party
|
||||
import com.daml.lf.language.LanguageDevConfig.EvaluationOrder
|
||||
import com.daml.lf.language.{Ast, LanguageMajorVersion, PackageInterface}
|
||||
import com.daml.lf.speedy.Speedy.{ContractInfo, UpdateMachine}
|
||||
import com.daml.lf.testing.parser.ParserParameters
|
||||
@ -196,7 +195,6 @@ private[speedy] object SpeedyTestLib {
|
||||
def typeAndCompile(
|
||||
majorLanguageVersion: LanguageMajorVersion,
|
||||
pkgs: Map[PackageId, Ast.Package],
|
||||
evaluationOrder: EvaluationOrder,
|
||||
): PureCompiledPackages = {
|
||||
require(
|
||||
pkgs.values.forall(pkg => pkg.languageVersion.major == majorLanguageVersion), {
|
||||
@ -213,20 +211,18 @@ private[speedy] object SpeedyTestLib {
|
||||
Compiler.Config
|
||||
.Dev(majorLanguageVersion)
|
||||
.copy(
|
||||
evaluationOrder = evaluationOrder,
|
||||
stacktracing = Compiler.FullStackTrace,
|
||||
stacktracing = Compiler.FullStackTrace
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@throws[ValidationError]
|
||||
def typeAndCompile[X](pkg: Ast.Package, evaluationOrder: EvaluationOrder)(implicit
|
||||
def typeAndCompile[X](pkg: Ast.Package)(implicit
|
||||
parserParameter: ParserParameters[X]
|
||||
): PureCompiledPackages =
|
||||
typeAndCompile(
|
||||
pkg.languageVersion.major,
|
||||
Map(parserParameter.defaultPackageId -> pkg),
|
||||
evaluationOrder,
|
||||
)
|
||||
|
||||
private[speedy] object Implicits {
|
||||
|
@ -6,7 +6,6 @@ package speedy
|
||||
|
||||
import java.util
|
||||
import com.daml.lf.language.{Ast, LanguageMajorVersion}
|
||||
import com.daml.lf.language.LanguageDevConfig.EvaluationOrder
|
||||
import com.daml.lf.speedy.SResult.SResultFinal
|
||||
import com.daml.lf.testing.parser.Implicits.SyntaxHelper
|
||||
import com.daml.lf.testing.parser.ParserParameters
|
||||
@ -28,126 +27,117 @@ class TailCallTest(majorLanguageVersion: LanguageMajorVersion)
|
||||
implicit val defaultParserParameters: ParserParameters[this.type] =
|
||||
ParserParameters.defaultFor[this.type](majorLanguageVersion)
|
||||
|
||||
for (evaluationOrder <- EvaluationOrder.valuesFor(majorLanguageVersion)) {
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(p"""
|
||||
module F {
|
||||
|
||||
evaluationOrder.toString - {
|
||||
// *Non* tail-recursive definition
|
||||
val triangle : (Int64 -> Int64) = \ (x: Int64) ->
|
||||
case (EQUAL @Int64 x 0) of
|
||||
True -> 0
|
||||
| _ -> ADD_INT64 x (F:triangle (SUB_INT64 x 1));
|
||||
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(
|
||||
p"""
|
||||
module F {
|
||||
// Tail-recursive definition, via helper function
|
||||
val triangleTR : (Int64 -> Int64) = F:triangleTR_acc 0;
|
||||
|
||||
// *Non* tail-recursive definition
|
||||
val triangle : (Int64 -> Int64) = \ (x: Int64) ->
|
||||
case (EQUAL @Int64 x 0) of
|
||||
True -> 0
|
||||
| _ -> ADD_INT64 x (F:triangle (SUB_INT64 x 1));
|
||||
|
||||
// Tail-recursive definition, via helper function
|
||||
val triangleTR : (Int64 -> Int64) = F:triangleTR_acc 0;
|
||||
|
||||
// Tail-recursive definition using accumulator parameter
|
||||
val triangleTR_acc : (Int64 -> Int64 -> Int64) = \ (acc: Int64) (x: Int64) ->
|
||||
case (EQUAL @Int64 x 0) of
|
||||
True -> acc
|
||||
| _ -> F:triangleTR_acc (ADD_INT64 acc x) (SUB_INT64 x 1);
|
||||
// Tail-recursive definition using accumulator parameter
|
||||
val triangleTR_acc : (Int64 -> Int64 -> Int64) = \ (acc: Int64) (x: Int64) ->
|
||||
case (EQUAL @Int64 x 0) of
|
||||
True -> acc
|
||||
| _ -> F:triangleTR_acc (ADD_INT64 acc x) (SUB_INT64 x 1);
|
||||
|
||||
|
||||
val triangle_viaFoldLeft : (Int64 -> Int64) = \ (x: Int64) ->
|
||||
FOLDL @Int64 @Int64 ADD_INT64 0 (F:generate Nil@Int64 x);
|
||||
val triangle_viaFoldLeft : (Int64 -> Int64) = \ (x: Int64) ->
|
||||
FOLDL @Int64 @Int64 ADD_INT64 0 (F:generate Nil@Int64 x);
|
||||
|
||||
val triangle_viaFoldRight : (Int64 -> Int64) = \ (x: Int64) ->
|
||||
FOLDR @Int64 @Int64 ADD_INT64 0 (F:generate Nil@Int64 x);
|
||||
val triangle_viaFoldRight : (Int64 -> Int64) = \ (x: Int64) ->
|
||||
FOLDR @Int64 @Int64 ADD_INT64 0 (F:generate Nil@Int64 x);
|
||||
|
||||
val triangle_viaFoldRight2 : (Int64 -> Int64) = \ (x: Int64) ->
|
||||
FOLDR @Int64 @Int64 (\(y: Int64) -> ADD_INT64 y) 0 (F:generate Nil@Int64 x);
|
||||
val triangle_viaFoldRight2 : (Int64 -> Int64) = \ (x: Int64) ->
|
||||
FOLDR @Int64 @Int64 (\(y: Int64) -> ADD_INT64 y) 0 (F:generate Nil@Int64 x);
|
||||
|
||||
// tail-recursive generator
|
||||
val generate : (List Int64 -> Int64 -> List Int64) = \ (acc: List Int64) (x: Int64) ->
|
||||
case (EQUAL @Int64 x 0) of
|
||||
True -> acc
|
||||
| _ -> F:generate (Cons @Int64 [x] acc) (SUB_INT64 x 1);
|
||||
// tail-recursive generator
|
||||
val generate : (List Int64 -> Int64 -> List Int64) = \ (acc: List Int64) (x: Int64) ->
|
||||
case (EQUAL @Int64 x 0) of
|
||||
True -> acc
|
||||
| _ -> F:generate (Cons @Int64 [x] acc) (SUB_INT64 x 1);
|
||||
|
||||
}
|
||||
""",
|
||||
evaluationOrder,
|
||||
)
|
||||
}
|
||||
""")
|
||||
|
||||
val small: Option[Int] = Some(5)
|
||||
val unbounded: Option[Int] = None
|
||||
val small: Option[Int] = Some(5)
|
||||
val unbounded: Option[Int] = None
|
||||
|
||||
// Evaluate an expression with optionally bounded env and kont stacks
|
||||
def runExpr(e: Ast.Expr, envBound: Option[Int], kontBound: Option[Int]): SValue = {
|
||||
// create the machine
|
||||
val machine = Speedy.Machine.fromPureExpr(pkgs, e)
|
||||
// maybe replace the env-stack with a bounded version
|
||||
envBound match {
|
||||
case None => ()
|
||||
case Some(bound) =>
|
||||
machine.env = new BoundedArrayList[SValue](bound)
|
||||
}
|
||||
// maybe replace the kont-stack with a bounded version
|
||||
kontBound match {
|
||||
case None => ()
|
||||
case Some(bound) =>
|
||||
val onlyKont: Speedy.Kont[Nothing] =
|
||||
if (machine.kontDepth() != 1) {
|
||||
crash(s"setBoundedKontStack, unexpected size of kont-stack: ${machine.kontDepth()}")
|
||||
} else {
|
||||
machine.peekKontStackTop()
|
||||
}
|
||||
machine.kontStack = new BoundedArrayList[Speedy.Kont[Nothing]](bound)
|
||||
machine.pushKont(onlyKont)
|
||||
}
|
||||
// run the machine
|
||||
machine.run() match {
|
||||
case SResultFinal(v) => v
|
||||
case res => crash(s"runExpr, unexpected result $res")
|
||||
}
|
||||
}
|
||||
|
||||
"A *non* tail-recursive definition requires an unbounded env-stack, and an unbounded kont-stack" in {
|
||||
val exp = e"F:triangle 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
// The point of this test is to prove that the bounded-evaluation checking really works.
|
||||
runExpr(exp, envBound = unbounded, kontBound = unbounded) shouldBe expected
|
||||
|
||||
the[RuntimeException]
|
||||
.thrownBy {
|
||||
runExpr(exp, envBound = small, kontBound = unbounded)
|
||||
}
|
||||
.toString() should include("BoundExceeded")
|
||||
|
||||
the[RuntimeException]
|
||||
.thrownBy {
|
||||
runExpr(exp, envBound = unbounded, kontBound = small)
|
||||
}
|
||||
.toString() should include("BoundExceeded")
|
||||
}
|
||||
|
||||
"A tail-recursive definition executes with a small env-stack, and a small kont-stack" in {
|
||||
val exp = e"F:triangleTR 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
runExpr(exp, envBound = small, kontBound = small) shouldBe expected
|
||||
}
|
||||
|
||||
"fold-left executes with a small env-stack, and a small kont-stack" in {
|
||||
val exp = e"F:triangle_viaFoldLeft 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
runExpr(exp, envBound = small, kontBound = small) shouldBe expected
|
||||
}
|
||||
|
||||
"fold-right executes with a small env-stack, and a small kont-stack" in {
|
||||
val exp = e"F:triangle_viaFoldRight 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
runExpr(exp, envBound = small, kontBound = small) shouldBe expected
|
||||
}
|
||||
|
||||
"fold-right (KFoldr1Map/Reduce case) executes with a small env-stack, and a small kont-stack" in {
|
||||
val exp = e"F:triangle_viaFoldRight2 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
runExpr(exp, envBound = small, kontBound = small) shouldBe expected
|
||||
}
|
||||
// Evaluate an expression with optionally bounded env and kont stacks
|
||||
def runExpr(e: Ast.Expr, envBound: Option[Int], kontBound: Option[Int]): SValue = {
|
||||
// create the machine
|
||||
val machine = Speedy.Machine.fromPureExpr(pkgs, e)
|
||||
// maybe replace the env-stack with a bounded version
|
||||
envBound match {
|
||||
case None => ()
|
||||
case Some(bound) =>
|
||||
machine.env = new BoundedArrayList[SValue](bound)
|
||||
}
|
||||
// maybe replace the kont-stack with a bounded version
|
||||
kontBound match {
|
||||
case None => ()
|
||||
case Some(bound) =>
|
||||
val onlyKont: Speedy.Kont[Nothing] =
|
||||
if (machine.kontDepth() != 1) {
|
||||
crash(s"setBoundedKontStack, unexpected size of kont-stack: ${machine.kontDepth()}")
|
||||
} else {
|
||||
machine.peekKontStackTop()
|
||||
}
|
||||
machine.kontStack = new BoundedArrayList[Speedy.Kont[Nothing]](bound)
|
||||
machine.pushKont(onlyKont)
|
||||
}
|
||||
// run the machine
|
||||
machine.run() match {
|
||||
case SResultFinal(v) => v
|
||||
case res => crash(s"runExpr, unexpected result $res")
|
||||
}
|
||||
}
|
||||
|
||||
"A *non* tail-recursive definition requires an unbounded env-stack, and an unbounded kont-stack" in {
|
||||
val exp = e"F:triangle 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
// The point of this test is to prove that the bounded-evaluation checking really works.
|
||||
runExpr(exp, envBound = unbounded, kontBound = unbounded) shouldBe expected
|
||||
|
||||
the[RuntimeException]
|
||||
.thrownBy {
|
||||
runExpr(exp, envBound = small, kontBound = unbounded)
|
||||
}
|
||||
.toString() should include("BoundExceeded")
|
||||
|
||||
the[RuntimeException]
|
||||
.thrownBy {
|
||||
runExpr(exp, envBound = unbounded, kontBound = small)
|
||||
}
|
||||
.toString() should include("BoundExceeded")
|
||||
}
|
||||
|
||||
"A tail-recursive definition executes with a small env-stack, and a small kont-stack" in {
|
||||
val exp = e"F:triangleTR 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
runExpr(exp, envBound = small, kontBound = small) shouldBe expected
|
||||
}
|
||||
|
||||
"fold-left executes with a small env-stack, and a small kont-stack" in {
|
||||
val exp = e"F:triangle_viaFoldLeft 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
runExpr(exp, envBound = small, kontBound = small) shouldBe expected
|
||||
}
|
||||
|
||||
"fold-right executes with a small env-stack, and a small kont-stack" in {
|
||||
val exp = e"F:triangle_viaFoldRight 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
runExpr(exp, envBound = small, kontBound = small) shouldBe expected
|
||||
}
|
||||
|
||||
"fold-right (KFoldr1Map/Reduce case) executes with a small env-stack, and a small kont-stack" in {
|
||||
val exp = e"F:triangle_viaFoldRight2 100"
|
||||
val expected = SValue.SInt64(5050)
|
||||
runExpr(exp, envBound = small, kontBound = small) shouldBe expected
|
||||
}
|
||||
|
||||
private case object BoundExceeded extends RuntimeException
|
||||
|
@ -6,7 +6,6 @@ package speedy
|
||||
|
||||
import com.daml.lf.data.{FrontStack, ImmArray, Ref}
|
||||
import com.daml.lf.data.Ref.{IdString, PackageId, Party, TypeConName}
|
||||
import com.daml.lf.language.LanguageDevConfig.{EvaluationOrder}
|
||||
import com.daml.lf.language.LanguageMajorVersion.{V1, V2}
|
||||
import com.daml.lf.language.{LanguageMajorVersion, LanguageVersion}
|
||||
import com.daml.lf.speedy.SBuiltin.{SBCastAnyContract, SBFetchAny}
|
||||
@ -33,117 +32,108 @@ class TransactionVersionTest(majorLanguageVersion: LanguageMajorVersion)
|
||||
val helpers = new TransactionVersionTestHelpers(majorLanguageVersion)
|
||||
import helpers._
|
||||
|
||||
for (evaluationOrder <- EvaluationOrder.valuesFor(majorLanguageVersion)) {
|
||||
"interface and transaction versioning" - {
|
||||
|
||||
evaluationOrder.toString - {
|
||||
"version testing assumptions" in {
|
||||
// TODO(#17366): remove this assumption once 2.0 is introduced
|
||||
assume(majorLanguageVersion == V1)
|
||||
oldVersion should be < newVersion
|
||||
Set(
|
||||
templatePkg.languageVersion,
|
||||
interfacesPkg.languageVersion,
|
||||
implementsPkg.languageVersion,
|
||||
coImplementsPkg.languageVersion,
|
||||
) shouldBe Set(commonVersion)
|
||||
}
|
||||
|
||||
"interface and transaction versioning" - {
|
||||
"template version > interface version" in {
|
||||
val oldPkg1 = templatePkg.copy(languageVersion = oldVersion)
|
||||
val oldPkg2 = interfacesPkg.copy(languageVersion = oldVersion)
|
||||
val newPkg1 = implementsPkg.copy(languageVersion = newVersion)
|
||||
val newPkg2 = coImplementsPkg.copy(languageVersion = newVersion)
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(
|
||||
majorLanguageVersion,
|
||||
Map(
|
||||
templatePkgId -> oldPkg1,
|
||||
interfacesPkgId -> oldPkg2,
|
||||
implementsPkgId -> newPkg1,
|
||||
coImplementsPkgId -> newPkg2,
|
||||
),
|
||||
)
|
||||
|
||||
"version testing assumptions" in {
|
||||
// TODO(#17366): remove this assumption once 2.0 is introduced
|
||||
assume(majorLanguageVersion == V1)
|
||||
oldVersion should be < newVersion
|
||||
Set(
|
||||
templatePkg.languageVersion,
|
||||
interfacesPkg.languageVersion,
|
||||
implementsPkg.languageVersion,
|
||||
coImplementsPkg.languageVersion,
|
||||
) shouldBe Set(commonVersion)
|
||||
for ((templateId, interfaceId, contract) <- testData) {
|
||||
val result = evaluateBeginExercise(
|
||||
pkgs,
|
||||
templateId,
|
||||
Some(interfaceId),
|
||||
contractId,
|
||||
committers = Set(contractParty),
|
||||
controllers = Set(contractParty),
|
||||
getContract = Map(contractId -> contract),
|
||||
)
|
||||
|
||||
inside(result) { case Right(transaction) =>
|
||||
transaction.version shouldBe TransactionVersion.assignNodeVersion(newVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"template version > interface version" in {
|
||||
val oldPkg1 = templatePkg.copy(languageVersion = oldVersion)
|
||||
val oldPkg2 = interfacesPkg.copy(languageVersion = oldVersion)
|
||||
val newPkg1 = implementsPkg.copy(languageVersion = newVersion)
|
||||
val newPkg2 = coImplementsPkg.copy(languageVersion = newVersion)
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(
|
||||
majorLanguageVersion,
|
||||
Map(
|
||||
templatePkgId -> oldPkg1,
|
||||
interfacesPkgId -> oldPkg2,
|
||||
implementsPkgId -> newPkg1,
|
||||
coImplementsPkgId -> newPkg2,
|
||||
),
|
||||
evaluationOrder,
|
||||
)
|
||||
"template version < interface version" in {
|
||||
val oldPkg1 = implementsPkg.copy(languageVersion = oldVersion)
|
||||
val oldPkg2 = coImplementsPkg.copy(languageVersion = oldVersion)
|
||||
val newPkg1 = templatePkg.copy(languageVersion = newVersion)
|
||||
val newPkg2 = interfacesPkg.copy(languageVersion = newVersion)
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(
|
||||
majorLanguageVersion,
|
||||
Map(
|
||||
templatePkgId -> newPkg1,
|
||||
interfacesPkgId -> newPkg2,
|
||||
implementsPkgId -> oldPkg1,
|
||||
coImplementsPkgId -> oldPkg2,
|
||||
),
|
||||
)
|
||||
|
||||
for ((templateId, interfaceId, contract) <- testData) {
|
||||
val result = evaluateBeginExercise(
|
||||
pkgs,
|
||||
templateId,
|
||||
Some(interfaceId),
|
||||
contractId,
|
||||
committers = Set(contractParty),
|
||||
controllers = Set(contractParty),
|
||||
getContract = Map(contractId -> contract),
|
||||
)
|
||||
for ((templateId, interfaceId, contract) <- testData) {
|
||||
val result = evaluateBeginExercise(
|
||||
pkgs,
|
||||
templateId,
|
||||
Some(interfaceId),
|
||||
contractId,
|
||||
committers = Set(contractParty),
|
||||
controllers = Set(contractParty),
|
||||
getContract = Map(contractId -> contract),
|
||||
)
|
||||
|
||||
inside(result) { case Right(transaction) =>
|
||||
transaction.version shouldBe TransactionVersion.assignNodeVersion(newVersion)
|
||||
}
|
||||
}
|
||||
inside(result) { case Right(transaction) =>
|
||||
transaction.version shouldBe TransactionVersion.assignNodeVersion(newVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"template version < interface version" in {
|
||||
val oldPkg1 = implementsPkg.copy(languageVersion = oldVersion)
|
||||
val oldPkg2 = coImplementsPkg.copy(languageVersion = oldVersion)
|
||||
val newPkg1 = templatePkg.copy(languageVersion = newVersion)
|
||||
val newPkg2 = interfacesPkg.copy(languageVersion = newVersion)
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(
|
||||
majorLanguageVersion,
|
||||
Map(
|
||||
templatePkgId -> newPkg1,
|
||||
interfacesPkgId -> newPkg2,
|
||||
implementsPkgId -> oldPkg1,
|
||||
coImplementsPkgId -> oldPkg2,
|
||||
),
|
||||
evaluationOrder,
|
||||
)
|
||||
"template version == interface version" in {
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(
|
||||
majorLanguageVersion,
|
||||
Map(
|
||||
templatePkgId -> templatePkg,
|
||||
interfacesPkgId -> interfacesPkg,
|
||||
implementsPkgId -> implementsPkg,
|
||||
coImplementsPkgId -> coImplementsPkg,
|
||||
),
|
||||
)
|
||||
|
||||
for ((templateId, interfaceId, contract) <- testData) {
|
||||
val result = evaluateBeginExercise(
|
||||
pkgs,
|
||||
templateId,
|
||||
Some(interfaceId),
|
||||
contractId,
|
||||
committers = Set(contractParty),
|
||||
controllers = Set(contractParty),
|
||||
getContract = Map(contractId -> contract),
|
||||
)
|
||||
for ((templateId, interfaceId, contract) <- testData) {
|
||||
val result = evaluateBeginExercise(
|
||||
pkgs,
|
||||
templateId,
|
||||
Some(interfaceId),
|
||||
contractId,
|
||||
committers = Set(contractParty),
|
||||
controllers = Set(contractParty),
|
||||
getContract = Map(contractId -> contract),
|
||||
)
|
||||
|
||||
inside(result) { case Right(transaction) =>
|
||||
transaction.version shouldBe TransactionVersion.assignNodeVersion(newVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"template version == interface version" in {
|
||||
val pkgs = SpeedyTestLib.typeAndCompile(
|
||||
majorLanguageVersion,
|
||||
Map(
|
||||
templatePkgId -> templatePkg,
|
||||
interfacesPkgId -> interfacesPkg,
|
||||
implementsPkgId -> implementsPkg,
|
||||
coImplementsPkgId -> coImplementsPkg,
|
||||
),
|
||||
evaluationOrder,
|
||||
)
|
||||
|
||||
for ((templateId, interfaceId, contract) <- testData) {
|
||||
val result = evaluateBeginExercise(
|
||||
pkgs,
|
||||
templateId,
|
||||
Some(interfaceId),
|
||||
contractId,
|
||||
committers = Set(contractParty),
|
||||
controllers = Set(contractParty),
|
||||
getContract = Map(contractId -> contract),
|
||||
)
|
||||
|
||||
inside(result) { case Right(transaction) =>
|
||||
transaction.version shouldBe TransactionVersion.assignNodeVersion(commonVersion)
|
||||
}
|
||||
}
|
||||
inside(result) { case Right(transaction) =>
|
||||
transaction.version shouldBe TransactionVersion.assignNodeVersion(commonVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,19 +15,4 @@ object LanguageDevConfig {
|
||||
sealed abstract class EvaluationOrder extends Product with Serializable
|
||||
case object LeftToRight extends EvaluationOrder
|
||||
case object RightToLeft extends EvaluationOrder
|
||||
|
||||
object EvaluationOrder {
|
||||
|
||||
// We can't test RightToLeft evaluation order with V1 because it only works in dev and V1 tests
|
||||
// will build packages for versions 1.14 and 1.15. It works by accident in V2 at the moment
|
||||
// because there's only one V2 version: 2.dev. Eventually, right-to-left evaluation will not be
|
||||
// dev-only but instead 2.x-only, for all V2 versions. Once we've done this refactoring we can
|
||||
// remove explicit evaluation orders from the tests.
|
||||
// TODO(#17366): make RightToLeft a v2.x feature and remove evaluation order flags everywhere
|
||||
def valuesFor(majorLanguageVersion: LanguageMajorVersion): List[EvaluationOrder] =
|
||||
majorLanguageVersion match {
|
||||
case LanguageMajorVersion.V1 => List(LeftToRight)
|
||||
case LanguageMajorVersion.V2 => List(LeftToRight, RightToLeft)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,11 @@
|
||||
package com.daml.lf.language
|
||||
|
||||
import com.daml.lf.LfVersions
|
||||
import com.daml.lf.language.LanguageDevConfig.{EvaluationOrder, LeftToRight, RightToLeft}
|
||||
import scalaz.{IList, NonEmptyList}
|
||||
|
||||
import scala.math.Ordering.Implicits.infixOrderingOps
|
||||
|
||||
// an ADT version of the Daml-LF version
|
||||
sealed abstract class LanguageMajorVersion(val pretty: String, minorAscending: List[String])
|
||||
extends LfVersions(
|
||||
@ -17,6 +20,8 @@ sealed abstract class LanguageMajorVersion(val pretty: String, minorAscending: L
|
||||
with Product
|
||||
with Serializable {
|
||||
|
||||
import LanguageMajorVersion._
|
||||
|
||||
// TODO(#17366): 2.dev is currently the only 2.x version, but as soon as 2.0 is introduced this
|
||||
// code should be simplified.
|
||||
val minStableVersion =
|
||||
@ -47,6 +52,12 @@ sealed abstract class LanguageMajorVersion(val pretty: String, minorAscending: L
|
||||
Left(s"LF $this.$minorVersion unsupported. Supported LF versions are ${supportedVersions
|
||||
.mkString(",")}")
|
||||
}
|
||||
|
||||
// TODO(#17366): Ideally this would be specified as a feature, but at the major version level.
|
||||
// We may want to allow expressing this once we rework feature specifications (see the TODO
|
||||
// on features).
|
||||
final def evaluationOrder: EvaluationOrder =
|
||||
if (this >= V2) RightToLeft else LeftToRight
|
||||
}
|
||||
|
||||
object LanguageMajorVersion {
|
||||
@ -65,7 +76,7 @@ object LanguageMajorVersion {
|
||||
|
||||
val All: List[LanguageMajorVersion] = List(V1, V2)
|
||||
|
||||
implicit val Ordering: scala.Ordering[LanguageMajorVersion] =
|
||||
implicit val languageMajorVersionOrdering: scala.Ordering[LanguageMajorVersion] =
|
||||
scala.Ordering.by(All.zipWithIndex.toMap)
|
||||
|
||||
def fromString(str: String): Option[LanguageMajorVersion] = str match {
|
||||
|
@ -22,7 +22,7 @@
|
||||
- well-authorized lookup is accepted: [AuthorizationSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/AuthorizationSpec.scala#L127)
|
||||
|
||||
## Availability:
|
||||
- Tail call optimization: Tail recursion does not blow the scala JVM stack.: [TailCallTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/TailCallTest.scala#L20)
|
||||
- Tail call optimization: Tail recursion does not blow the scala JVM stack.: [TailCallTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/TailCallTest.scala#L19)
|
||||
|
||||
## Confidentiality:
|
||||
- ensure correct privacy for create node: [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L38)
|
||||
@ -35,124 +35,124 @@
|
||||
- ensure correct privacy for rollback subtree: [BlindingSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/BlindingSpec.scala#L224)
|
||||
|
||||
## Integrity:
|
||||
- Evaluation order of create with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L587)
|
||||
- Evaluation order of create with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L610)
|
||||
- Evaluation order of create with contract key exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L663)
|
||||
- Evaluation order of create with create argument exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L637)
|
||||
- Evaluation order of create with duplicate contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L536)
|
||||
- Evaluation order of create with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L561)
|
||||
- Evaluation order of create with failed precondition: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L518)
|
||||
- Evaluation order of create_interface with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L789)
|
||||
- Evaluation order of create_interface with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L812)
|
||||
- Evaluation order of create_interface with contract key exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L865)
|
||||
- Evaluation order of create_interface with create argument exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L839)
|
||||
- Evaluation order of create_interface with duplicate contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L738)
|
||||
- Evaluation order of create_interface with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L763)
|
||||
- Evaluation order of create_interface with failed precondition: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L718)
|
||||
- Evaluation order of exercise by interface of a cached global contract that does not implement the interface.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1838)
|
||||
- Evaluation order of exercise by interface of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1820)
|
||||
- Evaluation order of exercise by interface of cached global contract with failed authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1880)
|
||||
- Evaluation order of exercise of a cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1184)
|
||||
- Evaluation order of exercise of a non-cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L939)
|
||||
- Evaluation order of exercise of a non-cached global contract with inconsistent key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L965)
|
||||
- Evaluation order of exercise of a wrongly typed cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1041)
|
||||
- Evaluation order of exercise of a wrongly typed non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L924)
|
||||
- Evaluation order of exercise of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1023)
|
||||
- Evaluation order of exercise of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1125)
|
||||
- Evaluation order of exercise of an unknown contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1209)
|
||||
- Evaluation order of exercise of an wrongly typed local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1145)
|
||||
- Evaluation order of exercise of cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1077)
|
||||
- Evaluation order of exercise with argument exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1223)
|
||||
- Evaluation order of exercise with output exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1251)
|
||||
- Evaluation order of exercise-by-key of a cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1476)
|
||||
- Evaluation order of exercise-by-key of a non-cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1356)
|
||||
- Evaluation order of exercise_by_key of a cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1544)
|
||||
- Evaluation order of exercise_by_key of a local contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1568)
|
||||
- Evaluation order of exercise_by_key of a non-cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1329)
|
||||
- Evaluation order of exercise_by_key of a wrongly typed cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1432)
|
||||
- Evaluation order of exercise_by_key of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1413)
|
||||
- Evaluation order of exercise_by_key of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1524)
|
||||
- Evaluation order of exercise_by_key of an unknown contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1603)
|
||||
- Evaluation order of exercise_by_key of cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1451)
|
||||
- Evaluation order of exercise_by_key with argument exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1618)
|
||||
- Evaluation order of exercise_by_key with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1693)
|
||||
- Evaluation order of exercise_by_key with result exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1647)
|
||||
- Evaluation order of exercise_interface of a cached local contract with failed authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1995)
|
||||
- Evaluation order of exercise_interface of a non-cached global contract with failed authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1764)
|
||||
- Evaluation order of exercise_interface of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1931)
|
||||
- Evaluation order of exercise_interface of an local contract not implementing the interface: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1950)
|
||||
- Evaluation order of exercise_vy_key with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1677)
|
||||
- Evaluation order of fetch of a cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2283)
|
||||
- Evaluation order of fetch of a non-cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2073)
|
||||
- Evaluation order of fetch of a non-cached global contract with inconsistent key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2096)
|
||||
- Evaluation order of fetch of a wrongly typed cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2161)
|
||||
- Evaluation order of fetch of a wrongly typed disclosed contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2303)
|
||||
- Evaluation order of fetch of a wrongly typed non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2058)
|
||||
- Evaluation order of fetch of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2144)
|
||||
- Evaluation order of fetch of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2230)
|
||||
- Evaluation order of fetch of an unknown contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2322)
|
||||
- Evaluation order of fetch of an wrongly typed local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2248)
|
||||
- Evaluation order of fetch of cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2195)
|
||||
- Evaluation order of fetch-by-key of a cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2493)
|
||||
- Evaluation order of fetch-by-key of a non-cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2409)
|
||||
- Evaluation order of fetch_by_key of a cached global contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2476)
|
||||
- Evaluation order of fetch_by_key of a local contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2552)
|
||||
- Evaluation order of fetch_by_key of a non-cached global contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2386)
|
||||
- Evaluation order of fetch_by_key of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2457)
|
||||
- Evaluation order of fetch_by_key of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2534)
|
||||
- Evaluation order of fetch_by_key of an unknown contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2581)
|
||||
- Evaluation order of fetch_by_key with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2613)
|
||||
- Evaluation order of fetch_by_key with contract key exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2627)
|
||||
- Evaluation order of fetch_by_key with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2597)
|
||||
- Evaluation order of fetch_interface of a cached global contract not implementing the interface.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2752)
|
||||
- Evaluation order of fetch_interface of a cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2880)
|
||||
- Evaluation order of fetch_interface of a non-cached global contract that doesn't implement interface.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2672)
|
||||
- Evaluation order of fetch_interface of a non-cached global contract with failed authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2691)
|
||||
- Evaluation order of fetch_interface of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2735)
|
||||
- Evaluation order of fetch_interface of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2825)
|
||||
- Evaluation order of fetch_interface of an local contract not implementing the interface: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2842)
|
||||
- Evaluation order of fetch_interface of an unknown contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2898)
|
||||
- Evaluation order of fetch_interface of cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2790)
|
||||
- Evaluation order of lookup of a cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3048)
|
||||
- Evaluation order of lookup of a non-cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2965)
|
||||
- Evaluation order of lookup_by_key of a cached global contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3031)
|
||||
- Evaluation order of lookup_by_key of a local contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3122)
|
||||
- Evaluation order of lookup_by_key of a local contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3106)
|
||||
- Evaluation order of lookup_by_key of a non-cached global contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2942)
|
||||
- Evaluation order of lookup_by_key of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3013)
|
||||
- Evaluation order of lookup_by_key of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3089)
|
||||
- Evaluation order of lookup_by_key of an unknown contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3152)
|
||||
- Evaluation order of lookup_by_key with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3184)
|
||||
- Evaluation order of lookup_by_key with contract key exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3198)
|
||||
- Evaluation order of lookup_by_key with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3168)
|
||||
- Evaluation order of successful create: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L494)
|
||||
- Evaluation order of successful create_interface: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L693)
|
||||
- Evaluation order of successful exercise by interface of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1718)
|
||||
- Evaluation order of successful exercise of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L999)
|
||||
- Evaluation order of successful exercise of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1102)
|
||||
- Evaluation order of successful exercise of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L897)
|
||||
- Evaluation order of successful exercise_by_key of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1387)
|
||||
- Evaluation order of successful exercise_by_key of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1500)
|
||||
- Evaluation order of successful exercise_by_key of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1285)
|
||||
- Evaluation order of successful exercise_interface of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1795)
|
||||
- Evaluation order of successful exercise_interface of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1907)
|
||||
- Evaluation order of successful fetch of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2127)
|
||||
- Evaluation order of successful fetch of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2215)
|
||||
- Evaluation order of successful fetch of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2035)
|
||||
- Evaluation order of successful fetch_by_key of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2440)
|
||||
- Evaluation order of successful fetch_by_key of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2518)
|
||||
- Evaluation order of successful fetch_by_key of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2341)
|
||||
- Evaluation order of successful fetch_interface of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2718)
|
||||
- Evaluation order of successful fetch_interface of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2810)
|
||||
- Evaluation order of successful fetch_interface of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2648)
|
||||
- Evaluation order of successful lookup_by_key of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2996)
|
||||
- Evaluation order of successful lookup_by_key of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3073)
|
||||
- Evaluation order of successful lookup_by_key of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2918)
|
||||
- Evaluation order of create with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L576)
|
||||
- Evaluation order of create with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L599)
|
||||
- Evaluation order of create with contract key exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L652)
|
||||
- Evaluation order of create with create argument exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L626)
|
||||
- Evaluation order of create with duplicate contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L525)
|
||||
- Evaluation order of create with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L550)
|
||||
- Evaluation order of create with failed precondition: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L507)
|
||||
- Evaluation order of create_interface with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L778)
|
||||
- Evaluation order of create_interface with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L801)
|
||||
- Evaluation order of create_interface with contract key exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L854)
|
||||
- Evaluation order of create_interface with create argument exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L828)
|
||||
- Evaluation order of create_interface with duplicate contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L727)
|
||||
- Evaluation order of create_interface with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L752)
|
||||
- Evaluation order of create_interface with failed precondition: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L707)
|
||||
- Evaluation order of exercise by interface of a cached global contract that does not implement the interface.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1823)
|
||||
- Evaluation order of exercise by interface of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1805)
|
||||
- Evaluation order of exercise by interface of cached global contract with failed authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1865)
|
||||
- Evaluation order of exercise of a cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1170)
|
||||
- Evaluation order of exercise of a non-cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L928)
|
||||
- Evaluation order of exercise of a non-cached global contract with inconsistent key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L954)
|
||||
- Evaluation order of exercise of a wrongly typed cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1028)
|
||||
- Evaluation order of exercise of a wrongly typed non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L913)
|
||||
- Evaluation order of exercise of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1011)
|
||||
- Evaluation order of exercise of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1112)
|
||||
- Evaluation order of exercise of an unknown contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1195)
|
||||
- Evaluation order of exercise of an wrongly typed local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1131)
|
||||
- Evaluation order of exercise of cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1064)
|
||||
- Evaluation order of exercise with argument exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1209)
|
||||
- Evaluation order of exercise with output exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1237)
|
||||
- Evaluation order of exercise-by-key of a cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1462)
|
||||
- Evaluation order of exercise-by-key of a non-cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1342)
|
||||
- Evaluation order of exercise_by_key of a cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1530)
|
||||
- Evaluation order of exercise_by_key of a local contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1554)
|
||||
- Evaluation order of exercise_by_key of a non-cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1315)
|
||||
- Evaluation order of exercise_by_key of a wrongly typed cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1418)
|
||||
- Evaluation order of exercise_by_key of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1399)
|
||||
- Evaluation order of exercise_by_key of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1510)
|
||||
- Evaluation order of exercise_by_key of an unknown contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1589)
|
||||
- Evaluation order of exercise_by_key of cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1437)
|
||||
- Evaluation order of exercise_by_key with argument exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1604)
|
||||
- Evaluation order of exercise_by_key with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1679)
|
||||
- Evaluation order of exercise_by_key with result exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1633)
|
||||
- Evaluation order of exercise_interface of a cached local contract with failed authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1979)
|
||||
- Evaluation order of exercise_interface of a non-cached global contract with failed authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1750)
|
||||
- Evaluation order of exercise_interface of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1915)
|
||||
- Evaluation order of exercise_interface of an local contract not implementing the interface: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1934)
|
||||
- Evaluation order of exercise_vy_key with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1663)
|
||||
- Evaluation order of fetch of a cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2264)
|
||||
- Evaluation order of fetch of a non-cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2057)
|
||||
- Evaluation order of fetch of a non-cached global contract with inconsistent key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2080)
|
||||
- Evaluation order of fetch of a wrongly typed cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2143)
|
||||
- Evaluation order of fetch of a wrongly typed disclosed contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2284)
|
||||
- Evaluation order of fetch of a wrongly typed non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2042)
|
||||
- Evaluation order of fetch of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2127)
|
||||
- Evaluation order of fetch of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2212)
|
||||
- Evaluation order of fetch of an unknown contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2303)
|
||||
- Evaluation order of fetch of an wrongly typed local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2229)
|
||||
- Evaluation order of fetch of cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2177)
|
||||
- Evaluation order of fetch-by-key of a cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2474)
|
||||
- Evaluation order of fetch-by-key of a non-cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2390)
|
||||
- Evaluation order of fetch_by_key of a cached global contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2457)
|
||||
- Evaluation order of fetch_by_key of a local contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2533)
|
||||
- Evaluation order of fetch_by_key of a non-cached global contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2367)
|
||||
- Evaluation order of fetch_by_key of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2438)
|
||||
- Evaluation order of fetch_by_key of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2515)
|
||||
- Evaluation order of fetch_by_key of an unknown contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2562)
|
||||
- Evaluation order of fetch_by_key with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2594)
|
||||
- Evaluation order of fetch_by_key with contract key exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2608)
|
||||
- Evaluation order of fetch_by_key with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2578)
|
||||
- Evaluation order of fetch_interface of a cached global contract not implementing the interface.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2733)
|
||||
- Evaluation order of fetch_interface of a cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2861)
|
||||
- Evaluation order of fetch_interface of a non-cached global contract that doesn't implement interface.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2653)
|
||||
- Evaluation order of fetch_interface of a non-cached global contract with failed authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2672)
|
||||
- Evaluation order of fetch_interface of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2716)
|
||||
- Evaluation order of fetch_interface of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2806)
|
||||
- Evaluation order of fetch_interface of an local contract not implementing the interface: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2823)
|
||||
- Evaluation order of fetch_interface of an unknown contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2879)
|
||||
- Evaluation order of fetch_interface of cached global contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2771)
|
||||
- Evaluation order of lookup of a cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3029)
|
||||
- Evaluation order of lookup of a non-cached global contract with visibility failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2946)
|
||||
- Evaluation order of lookup_by_key of a cached global contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3012)
|
||||
- Evaluation order of lookup_by_key of a local contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3103)
|
||||
- Evaluation order of lookup_by_key of a local contract with failure authorization: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3087)
|
||||
- Evaluation order of lookup_by_key of a non-cached global contract with authorization failure: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2923)
|
||||
- Evaluation order of lookup_by_key of an inactive global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2994)
|
||||
- Evaluation order of lookup_by_key of an inactive local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3070)
|
||||
- Evaluation order of lookup_by_key of an unknown contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3133)
|
||||
- Evaluation order of lookup_by_key with contract ID in contract key: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3165)
|
||||
- Evaluation order of lookup_by_key with contract key exceeding max nesting: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3179)
|
||||
- Evaluation order of lookup_by_key with empty contract key maintainers: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3149)
|
||||
- Evaluation order of successful create: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L483)
|
||||
- Evaluation order of successful create_interface: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L682)
|
||||
- Evaluation order of successful exercise by interface of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1704)
|
||||
- Evaluation order of successful exercise of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L987)
|
||||
- Evaluation order of successful exercise of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1089)
|
||||
- Evaluation order of successful exercise of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L886)
|
||||
- Evaluation order of successful exercise_by_key of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1373)
|
||||
- Evaluation order of successful exercise_by_key of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1486)
|
||||
- Evaluation order of successful exercise_by_key of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1271)
|
||||
- Evaluation order of successful exercise_interface of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1780)
|
||||
- Evaluation order of successful exercise_interface of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1891)
|
||||
- Evaluation order of successful fetch of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2110)
|
||||
- Evaluation order of successful fetch of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2197)
|
||||
- Evaluation order of successful fetch of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2019)
|
||||
- Evaluation order of successful fetch_by_key of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2421)
|
||||
- Evaluation order of successful fetch_by_key of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2499)
|
||||
- Evaluation order of successful fetch_by_key of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2322)
|
||||
- Evaluation order of successful fetch_interface of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2699)
|
||||
- Evaluation order of successful fetch_interface of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2791)
|
||||
- Evaluation order of successful fetch_interface of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2629)
|
||||
- Evaluation order of successful lookup_by_key of a cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2977)
|
||||
- Evaluation order of successful lookup_by_key of a local contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L3054)
|
||||
- Evaluation order of successful lookup_by_key of a non-cached global contract: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2899)
|
||||
- Exceptions, throw/catch.: [ExceptionTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ExceptionTest.scala#L30)
|
||||
- Rollback creates cannot be exercise: [EngineTest.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala#L2103)
|
||||
- This checks that type checking in exercise_interface is done after checking activeness.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1975)
|
||||
- This checks that type checking is done after checking activeness.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1862)
|
||||
- This checks that type checking is done after checking activeness.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2862)
|
||||
- This checks that type checking in exercise_interface is done after checking activeness.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1959)
|
||||
- This checks that type checking is done after checking activeness.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1847)
|
||||
- This checks that type checking is done after checking activeness.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L2843)
|
||||
- contract key behaviour (non-unique mode): [ContractKeySpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ContractKeySpec.scala#L408)
|
||||
- contract key behaviour (unique mode): [ContractKeySpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ContractKeySpec.scala#L418)
|
||||
- contract keys must have a non-empty set of maintainers: [ContractKeySpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ContractKeySpec.scala#L224)
|
||||
@ -161,7 +161,7 @@
|
||||
- ensure builtin operators have the correct type: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L66)
|
||||
- ensure expression forms have the correct type: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L126)
|
||||
- exercise-by-interface command is rejected for a: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L187)
|
||||
- exercise_interface with a contract instance that does not implement the interface fails.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1746)
|
||||
- exercise_interface with a contract instance that does not implement the interface fails.: [EvaluationOrderTest.scala](daml-lf/interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/EvaluationOrderTest.scala#L1732)
|
||||
- ill-formed create API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L175)
|
||||
- ill-formed create replay command is rejected: [ReplayCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ReplayCommandPreprocessorSpec.scala#L124)
|
||||
- ill-formed create-and-exercise API command is rejected: [ApiCommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/ApiCommandPreprocessorSpec.scala#L200)
|
||||
|
Loading…
Reference in New Issue
Block a user