diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 6f12d8e0f9..8f5f72c931 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -259,7 +259,7 @@ case object MinerPubkey extends NotReadyValueByteArray with ValueCompanion { } /** When interpreted evaluates to a IntConstant built from Context.currentHeight */ -case object Height extends NotReadyValueInt with ValueCompanion { +case object Height extends NotReadyValueInt with FixedCostValueCompanion { override def companion = this override def opCode: OpCode = OpCodes.HeightCode /** Cost of: 1) Calling Context.HEIGHT Scala method. */ @@ -272,7 +272,7 @@ case object Height extends NotReadyValueInt with ValueCompanion { } /** When interpreted evaluates to a collection of BoxConstant built from Context.boxesToSpend */ -case object Inputs extends LazyCollection[SBox.type] with ValueCompanion { +case object Inputs extends LazyCollection[SBox.type] with FixedCostValueCompanion { override def companion = this override def opCode: OpCode = OpCodes.InputsCode /** Cost of: 1) Calling Context.INPUTS Scala method. */ @@ -286,7 +286,7 @@ case object Inputs extends LazyCollection[SBox.type] with ValueCompanion { } /** When interpreted evaluates to a collection of BoxConstant built from Context.spendingTransaction.outputs */ -case object Outputs extends LazyCollection[SBox.type] with ValueCompanion { +case object Outputs extends LazyCollection[SBox.type] with FixedCostValueCompanion { override def companion = this override def opCode: OpCode = OpCodes.OutputsCode /** Cost of: 1) Calling Context.OUTPUTS Scala method. */ @@ -316,7 +316,7 @@ case object LastBlockUtxoRootHash extends NotReadyValueAvlTree with ValueCompani /** When interpreted evaluates to a BoxConstant built from context.boxesToSpend(context.selfIndex) */ -case object Self extends NotReadyValueBox with ValueCompanion { +case object Self extends NotReadyValueBox with FixedCostValueCompanion { override def companion = this override def opCode: OpCode = OpCodes.SelfCode /** Cost of: 1) Calling Context.SELF Scala method. */ @@ -349,7 +349,7 @@ case object Context extends NotReadyValue[SContext.type] with ValueCompanion { /** When interpreted evaluates to the singleton instance of [[special.sigma.SigmaDslBuilder]]. * Corresponds to `Global` variable in ErgoScript which can be used like `Global.groupGenerator`. */ -case object Global extends NotReadyValue[SGlobal.type] with ValueCompanion { +case object Global extends NotReadyValue[SGlobal.type] with FixedCostValueCompanion { override def companion = this override def opCode: OpCode = OpCodes.GlobalCode /** Cost of: 1) accessing Global instance. */ diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index 5e015d2ceb..fe177ecb68 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -998,7 +998,7 @@ object Values { Colls.fromArray(is) } } - object ConcreteCollection extends ValueCompanion { + object ConcreteCollection extends FixedCostValueCompanion { override def opCode: OpCode = ConcreteCollectionCode /** Cost of: allocating new collection * @see ConcreteCollection_PerItem */ diff --git a/sigmastate/src/main/scala/sigmastate/lang/Terms.scala b/sigmastate/src/main/scala/sigmastate/lang/Terms.scala index b3d5fb3680..e8a1df33cd 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/Terms.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/Terms.scala @@ -248,7 +248,7 @@ object Terms { } } - object MethodCall extends ValueCompanion { + object MethodCall extends FixedCostValueCompanion { override def opCode: OpCode = OpCodes.MethodCallCode /** Cost of: 1) packing args into Array 2) java.lang.reflect.Method.invoke */ override val costKind = FixedCost(JitCost(4)) diff --git a/sigmastate/src/main/scala/sigmastate/trees.scala b/sigmastate/src/main/scala/sigmastate/trees.scala index 0759f13b52..35f88bd956 100644 --- a/sigmastate/src/main/scala/sigmastate/trees.scala +++ b/sigmastate/src/main/scala/sigmastate/trees.scala @@ -168,7 +168,7 @@ case class BoolToSigmaProp(value: BoolValue) extends SigmaPropValue { SigmaDsl.sigmaProp(v) } } -object BoolToSigmaProp extends ValueCompanion { +object BoolToSigmaProp extends FixedCostValueCompanion { override def opCode: OpCode = OpCodes.BoolToSigmaPropCode override val costKind = FixedCost(JitCost(15)) val OpType = SFunc(SBoolean, SSigmaProp) @@ -186,7 +186,7 @@ case class CreateProveDlog(value: Value[SGroupElement.type]) extends SigmaPropVa SigmaDsl.proveDlog(v) } } -object CreateProveDlog extends ValueCompanion { +object CreateProveDlog extends FixedCostValueCompanion { override def opCode: OpCode = OpCodes.ProveDlogCode override val costKind = FixedCost(JitCost(10)) val OpType = SFunc(SGroupElement, SSigmaProp) @@ -227,7 +227,7 @@ case class CreateProveDHTuple(gv: Value[SGroupElement.type], SigmaDsl.proveDHTuple(g, h, u, v) } } -object CreateProveDHTuple extends ValueCompanion { +object CreateProveDHTuple extends FixedCostValueCompanion { override def opCode: OpCode = OpCodes.ProveDiffieHellmanTupleCode override val costKind = FixedCost(JitCost(20)) } @@ -1019,7 +1019,7 @@ case class Negation[T <: SType](input: Value[T]) extends OneArgumentOperation[T, i.negate(inputV) } } -object Negation extends OneArgumentOperationCompanion { +object Negation extends OneArgumentOperationCompanion with FixedCostValueCompanion { override def opCode: OpCode = OpCodes.NegationCode override val costKind = FixedCost(JitCost(30)) override def argInfos: Seq[ArgInfo] = NegationInfo.argInfos @@ -1498,7 +1498,7 @@ case class If[T <: SType](condition: Value[SBoolean.type], trueBranch: Value[T], } } } -object If extends QuadrupleCompanion { +object If extends QuadrupleCompanion with FixedCostValueCompanion { override def opCode: OpCode = OpCodes.IfCode /** Cost of: conditional switching to the right branch (excluding the cost both * condition itself and the branches) */ diff --git a/sigmastate/src/main/scala/sigmastate/types.scala b/sigmastate/src/main/scala/sigmastate/types.scala index dcfdadf5fc..d173d4d4ff 100644 --- a/sigmastate/src/main/scala/sigmastate/types.scala +++ b/sigmastate/src/main/scala/sigmastate/types.scala @@ -1688,9 +1688,6 @@ object SCollection extends STypeCompanion with MethodByNameUnapply { */ def flatMap_eval[A, B](mc: MethodCall, xs: Coll[A], f: A => Coll[B]) (implicit E: ErgoTreeEvaluator): Coll[B] = { - if (!VersionContext.current.isJitActivated) { - checkValidFlatmap(mc) - } val m = mc.method var res: Coll[B] = null E.addSeqCost(m.costKind.asInstanceOf[PerItemCost], m.opDesc) { () => diff --git a/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala b/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala index c9022c4b1b..fe6a5cfd9e 100644 --- a/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala +++ b/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala @@ -280,7 +280,7 @@ case class ByIndex[V <: SType](input: Value[SCollection[V]], } } } -object ByIndex extends ValueCompanion { +object ByIndex extends FixedCostValueCompanion { override def opCode: OpCode = OpCodes.ByIndexCode override val costKind = FixedCost(JitCost(30)) } @@ -364,7 +364,7 @@ case class SizeOf[V <: SType](input: Value[SCollection[V]]) inputV.length } } -object SizeOf extends SimpleTransformerCompanion { +object SizeOf extends SimpleTransformerCompanion with FixedCostValueCompanion { val OpType = SFunc(SCollection(SType.tIV), SInt) override def opCode: OpCode = OpCodes.SizeOfCode /** Cost of: 1) calling Coll.length method (guaranteed to be O(1)) @@ -387,7 +387,7 @@ case class ExtractAmount(input: Value[SBox.type]) extends Extract[SLong.type] wi inputV.value } } -object ExtractAmount extends SimpleTransformerCompanion { +object ExtractAmount extends SimpleTransformerCompanion with FixedCostValueCompanion { val OpType = SFunc(SBox, SLong) override def opCode: OpCode = OpCodes.ExtractAmountCode /** Cost of: 1) access `value` property of a [[special.sigma.Box]] */ @@ -408,7 +408,7 @@ case class ExtractScriptBytes(input: Value[SBox.type]) extends Extract[SByteArra inputV.propositionBytes } } -object ExtractScriptBytes extends SimpleTransformerCompanion { +object ExtractScriptBytes extends SimpleTransformerCompanion with FixedCostValueCompanion { val OpType = SFunc(SBox, SByteArray) override def opCode: OpCode = OpCodes.ExtractScriptBytesCode @@ -495,7 +495,7 @@ case class ExtractRegisterAs[V <: SType]( input: Value[SBox.type], inputV.getReg(registerId.number)(tV) } } -object ExtractRegisterAs extends ValueCompanion { +object ExtractRegisterAs extends FixedCostValueCompanion { override def opCode: OpCode = OpCodes.ExtractRegisterAs /** CostOf: 1) accessing `registers` collection 2) comparing types 3) allocating Some()*/ override val costKind = FixedCost(JitCost(50)) @@ -625,7 +625,7 @@ case class OptionGetOrElse[V <: SType](input: Value[SOption[V]], default: Value[ inputV.getOrElse(dV) } } -object OptionGetOrElse extends ValueCompanion { +object OptionGetOrElse extends ValueCompanion with FixedCostValueCompanion { override def opCode: OpCode = OpCodes.OptionGetOrElseCode /** Cost of: 1) Calling Option.getOrElse Scala method. */ override val costKind = FixedCost(JitCost(20)) @@ -643,7 +643,7 @@ case class OptionIsDefined[V <: SType](input: Value[SOption[V]]) inputV.isDefined } } -object OptionIsDefined extends SimpleTransformerCompanion { +object OptionIsDefined extends SimpleTransformerCompanion with FixedCostValueCompanion { override def opCode: OpCode = OpCodes.OptionIsDefinedCode /** Cost of: 1) Calling Option.isDefined Scala method. */ override val costKind = FixedCost(JitCost(10)) diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala index 2a161923ee..09238a0cc0 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala @@ -115,10 +115,18 @@ class SigmaDslSpecification extends SigmaDslTesting forAll(table) { (x, expectedRes) => val res = f.checkEquality(x) val resValue = res.map(_._1) - val expected = expectedRes.newResults(ergoTreeVersionInTests)._1 - checkResult(resValue, expected.value, failOnTestVectors = true) - if (res.isSuccess) { - res.get._2.cost shouldBe JitCost(expected.verificationCost.get) + val (expected, expDetailsOpt) = expectedRes.newResults(ergoTreeVersionInTests) + checkResult(resValue, expected.value, failOnTestVectors = true, + "SigmaDslSpecifiction#testCases: compare expected new result with res = f.checkEquality(x)") + res match { + case Success((value, details)) => + details.cost shouldBe JitCost(expected.verificationCost.get) + expDetailsOpt.foreach(expDetails => + if (details.trace != expDetails.trace) { + printCostDetails(f.script, details) + details.trace shouldBe expDetails.trace + } + ) } } } @@ -140,6 +148,80 @@ class SigmaDslSpecification extends SigmaDslTesting prepareSamples[(Header, Header)] } + ///===================================================== + /// CostDetails shared among test cases + ///----------------------------------------------------- + val traceBase = Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), + FixedCostItem(ValUse) + ) + def upcastCostDetails(tpe: SType) = TracedCost(traceBase :+ TypeBasedCostItem(Upcast, tpe)) + def downcastCostDetails(tpe: SType) = TracedCost(traceBase :+ TypeBasedCostItem(Downcast, tpe)) + def arithOpsCostDetails(tpe: SType) = CostDetails( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Plus, tpe), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Minus, tpe), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Multiply, tpe), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Division, tpe), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Modulo, tpe), + FixedCostItem(Tuple), + FixedCostItem(Tuple), + FixedCostItem(Tuple), + FixedCostItem(Tuple) + ) + ) + + def binaryRelationCostDetails(rel: RelationCompanion, tpe: SType) = CostDetails( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(rel, tpe) + ) + ) + def costNEQ(neqCost: Seq[CostItem]) = CostDetails( + traceBase ++ + Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField) + ) ++ + neqCost + ) + + def methodCostDetails(sMethod: SMethod, methodCost: Int) = TracedCost( + traceBase ++ Array( + FixedCostItem(PropertyCall), + FixedCostItem(sMethod, FixedCost(JitCost(methodCost))) + ) + ) + ///===================================================== /// Boolean type operations ///----------------------------------------------------- @@ -165,26 +247,21 @@ class SigmaDslSpecification extends SigmaDslTesting SelectField.typed[BoolValue](ValUse(1, STuple(Vector(SBoolean, SBoolean))), 2.toByte) ) )) - val trace = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails = CostDetails( + traceBase ++ Array( FixedCostItem(SelectField), FixedCostItem(ValUse), FixedCostItem(SelectField), FixedCostItem(BinXor) ) ) - val newCost = 1788 + val newCost = 1788 + def success(b: Boolean) = Expected(Success(b), 36518, newDetails, newCost) val cases = Seq( - (true, true) -> Expected(Success(false), 36518, trace, newCost), - (true, false) -> Expected(Success(true), 36518, trace, newCost), - (false, false) -> Expected(Success(false), 36518, trace, newCost), - (false, true) -> Expected(Success(true), 36518, trace, newCost) + (true, true) -> success(false), + (true, false) -> success(true), + (false, false) -> success(false), + (false, true) -> success(true) ) verifyCases(cases, binXor) } @@ -196,19 +273,26 @@ class SigmaDslSpecification extends SigmaDslTesting Vector((1, STuple(Vector(SBoolean, SBoolean)))), BinXor( SelectField.typed[BoolValue](ValUse(1, STuple(Vector(SBoolean, SBoolean))), 1.toByte), - SelectField.typed[BoolValue](ValUse(1, STuple(Vector(SBoolean, SBoolean))), 2.toByte) - ) - )) + SelectField.typed[BoolValue](ValUse(1, STuple(Vector(SBoolean, SBoolean))), 2.toByte)))) + val newDetails = CostDetails( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(BinXor) + ) + ) val expectedCost = 36518 + val newCost = 1788 val cases = Seq( - (true, true) -> Expected(Success(false), expectedCost) + (true, true) -> Expected(Success(false), expectedCost, newDetails, newCost) ) verifyCases(cases, feature) val initCost = 100 initialCostInTests.withValue(initCost) { val cases = Seq( - (true, true) -> Expected(Success(false), expectedCost + initCost) + (true, true) -> Expected(Success(false), expectedCost + initCost, newDetails, newCost + initCost) ) verifyCases(cases, feature) } @@ -227,14 +311,8 @@ class SigmaDslSpecification extends SigmaDslTesting SelectField.typed[BoolValue](ValUse(1, STuple(Vector(SInt, SBoolean))), 2.toByte) ) )) - val newCost = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), - FixedCostItem(ValUse), + val newDetails = CostDetails( + traceBase ++ Array( FixedCostItem(SelectField), FixedCostItem(Constant), FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), @@ -243,13 +321,14 @@ class SigmaDslSpecification extends SigmaDslTesting FixedCostItem(BinXor) ) ) + def success(b: Boolean) = Expected(Success(b), 36865, newDetails, 1789) val cases = Seq( - (1095564593, true) -> Expected(Success(true), 36865, newCost), - (-901834021, true) -> Expected(Success(true), 36865, newCost), - (595045530, false) -> Expected(Success(false), 36865, newCost), - (-1157998227, false) -> Expected(Success(false), 36865, newCost), - (0, true) -> Expected(Success(false), 36865, newCost), - (0, false) -> Expected(Success(true), 36865, newCost) + (1095564593, true) -> success(true), + (-901834021, true) -> success(true), + (595045530, false) -> success(false), + (-1157998227, false) -> success(false), + (0, true) -> success(false), + (0, false) -> success(true) ) verifyCases(cases, xor) } @@ -264,24 +343,14 @@ class SigmaDslSpecification extends SigmaDslTesting SelectField.typed[BoolValue](ValUse(1, STuple(Vector(SBoolean, SBoolean))), 2.toByte) ) )) - val cost1 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails1 = CostDetails( + traceBase ++ Array( FixedCostItem(SelectField), FixedCostItem(BinAnd) ) ) - val cost2 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails2 = CostDetails( + traceBase ++ Array( FixedCostItem(SelectField), FixedCostItem(BinAnd), FixedCostItem(ValUse), @@ -289,10 +358,10 @@ class SigmaDslSpecification extends SigmaDslTesting ) ) val cases = Seq( - (false, true) -> Expected(Success(false), 38241, cost1), - (false, false) -> Expected(Success(false), 38241, cost1), - (true, true) -> Expected(Success(true), 38241, cost2), - (true, false) -> Expected(Success(false), 38241, cost2) + (false, true) -> Expected(Success(false), 38241, newDetails1, 1786), + (false, false) -> Expected(Success(false), 38241, newDetails1, 1786), + (true, true) -> Expected(Success(true), 38241, newDetails2, 1788), + (true, false) -> Expected(Success(false), 38241, newDetails2, 1788) ) verifyCases(cases, eq) } @@ -307,79 +376,50 @@ class SigmaDslSpecification extends SigmaDslTesting SelectField.typed[BoolValue](ValUse(1, STuple(Vector(SBoolean, SBoolean))), 2.toByte) ) )) - val cost1 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails1 = CostDetails( + traceBase ++ Array( FixedCostItem(SelectField), FixedCostItem(BinOr) ) ) - val cost2 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails2 = CostDetails( + traceBase ++ Array( FixedCostItem(SelectField), FixedCostItem(BinOr), FixedCostItem(ValUse), FixedCostItem(SelectField) ) ) + val cost = 38241 val cases = Seq( - (true, false) -> Expected(Success(true), 38241, cost1), - (true, true) -> Expected(Success(true), 38241, cost1), - (false, false) -> Expected(Success(false), 38241, cost2), - (false, true) -> Expected(Success(true), 38241, cost2) + (true, false) -> Expected(Success(true), cost, newDetails1, 1786), + (true, true) -> Expected(Success(true), cost, newDetails1, 1786), + (false, false) -> Expected(Success(false), cost, newDetails2, 1788), + (false, true) -> Expected(Success(true), cost, newDetails2, 1788) ) verifyCases(cases, eq) } def runLazy_And_Or_BooleanEquivalence(implicit evalSettings: EvalSettings) = { - val cost1 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails1 = CostDetails( + traceBase ++ Array( FixedCostItem(BinOr) ) ) - val cost2 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails2 = CostDetails( + traceBase ++ Array( FixedCostItem(BinAnd) ) ) - val cost3 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails3 = CostDetails( + traceBase ++ Array( FixedCostItem(BinAnd), FixedCostItem(ValUse), FixedCostItem(BinOr) ) ) - val cost4 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails4 = CostDetails( + traceBase ++ Array( FixedCostItem(BinAnd), FixedCostItem(ValUse), FixedCostItem(BinAnd), @@ -387,13 +427,8 @@ class SigmaDslSpecification extends SigmaDslTesting FixedCostItem(BinOr) ) ) - val cost5 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails5 = CostDetails( + traceBase ++ Array( FixedCostItem(BinAnd), FixedCostItem(ValUse), FixedCostItem(BinAnd), @@ -405,7 +440,7 @@ class SigmaDslSpecification extends SigmaDslTesting ) verifyCases( Seq( - (true, Expected(Success(true), 38467, cost1)), + (true, Expected(Success(true), 38467, newDetails1, 1785)), (false, Expected(new ArithmeticException("/ by zero"))) ), existingFeature((x: Boolean) => x || (1 / 0 == 1), @@ -421,7 +456,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( (true, Expected(new ArithmeticException("/ by zero"))), - (false, Expected(Success(false), 38467, cost2)) + (false, Expected(Success(false), 38467, newDetails2, 1785)) ), existingFeature((x: Boolean) => x && (1 / 0 == 1), "{ (x: Boolean) => x && (1 / 0 == 1) }", @@ -435,8 +470,8 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - (false, Expected(Success(false), 40480, cost2)), - (true, Expected(Success(true), 40480, cost3)) + (false, Expected(Success(false), 40480, newDetails2, 1785)), + (true, Expected(Success(true), 40480, newDetails3, 1788)) ), existingFeature((x: Boolean) => x && (x || (1 / 0 == 1)), "{ (x: Boolean) => x && (x || (1 / 0 == 1)) }", @@ -453,8 +488,8 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - (false, Expected(Success(false), 42493, cost2)), - (true, Expected(Success(true), 42493, cost4)) + (false, Expected(Success(false), 42493, newDetails2, 1785)), + (true, Expected(Success(true), 42493, newDetails4, 1790)) ), existingFeature((x: Boolean) => x && (x && (x || (1 / 0 == 1))), "{ (x: Boolean) => x && (x && (x || (1 / 0 == 1))) }", @@ -474,8 +509,8 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - (false, Expected(Success(false), 44506, cost2)), - (true, Expected(Success(true), 44506, cost5)) + (false, Expected(Success(false), 44506, newDetails2, 1785)), + (true, Expected(Success(true), 44506, newDetails5, 1793)) ), existingFeature((x: Boolean) => x && (x && (x && (x || (1 / 0 == 1)))), "{ (x: Boolean) => x && (x && (x && (x || (1 / 0 == 1)))) }", @@ -496,13 +531,8 @@ class SigmaDslSpecification extends SigmaDslTesting ) ))) - val cost6 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails6 = CostDetails( + traceBase ++ Array( FixedCostItem(LogicalNot), FixedCostItem(BinAnd), FixedCostItem(LogicalNot), @@ -514,7 +544,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( (false, Expected(new ArithmeticException("/ by zero"))), - (true, Expected(Success(true), 43281, cost6)) + (true, Expected(Success(true), 43281, newDetails6, 1793)) ), existingFeature((x: Boolean) => !(!x && (1 / 0 == 1)) && (x || (1 / 0 == 1)), "{ (x: Boolean) => !(!x && (1 / 0 == 1)) && (x || (1 / 0 == 1)) }", @@ -534,14 +564,8 @@ class SigmaDslSpecification extends SigmaDslTesting ) ))) - val cost7 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails7 = CostDetails( + traceBase ++ Array( FixedCostItem(BinOr), FixedCostItem(BinAnd), FixedCostItem(ValUse) @@ -549,7 +573,7 @@ class SigmaDslSpecification extends SigmaDslTesting ) verifyCases( Seq( - (true, Expected(Success(true), 40480, cost7)), + (true, Expected(Success(true), 40480, newDetails7, 1788)), (false, Expected(new ArithmeticException("/ by zero"))) ), existingFeature((x: Boolean) => (x || (1 / 0 == 1)) && x, @@ -565,14 +589,8 @@ class SigmaDslSpecification extends SigmaDslTesting ) ))) - val cost8 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails8 = CostDetails( + traceBase ++ Array( FixedCostItem(BinOr), FixedCostItem(BinAnd), FixedCostItem(ValUse), @@ -581,7 +599,7 @@ class SigmaDslSpecification extends SigmaDslTesting ) verifyCases( Seq( - (true, Expected(Success(true), 43149, cost8)), + (true, Expected(Success(true), 43149, newDetails8, 1790)), (false, Expected(new ArithmeticException("/ by zero"))) ), existingFeature((x: Boolean) => (x || (1 / 0 == 1)) && (x || (1 / 0 == 1)), @@ -600,14 +618,8 @@ class SigmaDslSpecification extends SigmaDslTesting ) ))) - val cost9 = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val newDetails9 = CostDetails( + traceBase ++ Array( FixedCostItem(LogicalNot), FixedCostItem(BinAnd), FixedCostItem(LogicalNot), @@ -619,7 +631,7 @@ class SigmaDslSpecification extends SigmaDslTesting ) verifyCases( Seq( - (true, Expected(Success(true), 45950, cost9)), + (true, Expected(Success(true), 45950, newDetails9, 1795)), (false, Expected(new ArithmeticException("/ by zero"))) ), existingFeature( @@ -644,7 +656,7 @@ class SigmaDslSpecification extends SigmaDslTesting ) ))) - val cost10 = CostDetails( + val newDetails10 = CostDetails( Array( FixedCostItem(Apply), FixedCostItem(FuncValue), @@ -669,7 +681,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( (false, Expected(new ArithmeticException("/ by zero"))), - (true, Expected(Success(true), 48862, cost10)) + (true, Expected(Success(true), 48862, newDetails10, 1800)) ), existingFeature( (x: Boolean) => (!(!x && (1 / 0 == 1)) || (1 / 0 == 0)) && (!(!x && (1 / 0 == 1)) || (1 / 0 == 1)), @@ -704,70 +716,7 @@ class SigmaDslSpecification extends SigmaDslTesting property("lazy || and && boolean equivalence") { runLazy_And_Or_BooleanEquivalence(evalSettings) - } - - val costIdentity = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse) - ) - ) - val costUpcast = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse) - ) - ) - val costDowncast = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse) - ) - ) - def costArithOps(tpe: SType) = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Plus, tpe), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Minus, tpe), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Multiply, tpe), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Division, tpe), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Modulo, tpe), - FixedCostItem(Tuple), - FixedCostItem(Tuple), - FixedCostItem(Tuple), - FixedCostItem(Tuple) - ) - ) + } property("Byte methods equivalence") { SByte.upcast(0.toByte) shouldBe 0.toByte // boundary test case @@ -775,7 +724,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def expect(v: Byte) = Expected(Success(v), 35798, costIdentity) + def expect(v: Byte) = Expected(Success(v), 35798, TracedCost(traceBase), 1783) Seq( (0.toByte, expect(0.toByte)), (1.toByte, expect(1.toByte)), @@ -792,7 +741,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def expected(v: Short) = Expected(Success(v), 35902, costUpcast) + def expected(v: Short) = Expected(Success(v), 35902, upcastCostDetails(SShort), 1784) Seq( (0.toByte, expected(0.toShort)), (1.toByte, expected(1.toShort)), @@ -809,7 +758,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def expected(v: Int) = Expected(Success(v), 35902, costUpcast) + def expected(v: Int) = Expected(Success(v), 35902, upcastCostDetails(SInt), 1784) Seq( (0.toByte, expected(0)), (1.toByte, expected(1)), @@ -826,7 +775,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def expected(v: Long) = Expected(Success(v), 35902, costUpcast) + def expected(v: Long) = Expected(Success(v), 35902, upcastCostDetails(SLong), 1784) Seq( (0.toByte, expected(0L)), (1.toByte, expected(1L)), @@ -843,7 +792,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def expected(v: BigInt) = Expected(Success(v), 35932, costUpcast) + def expected(v: BigInt) = Expected(Success(v), 35932, upcastCostDetails(SBigInt), 1787) Seq( (0.toByte, expected(CBigInt(new BigInteger("0", 16)))), (1.toByte, expected(CBigInt(new BigInteger("1", 16)))), @@ -861,7 +810,7 @@ class SigmaDslSpecification extends SigmaDslTesting val n = ExactIntegral.ByteIsExactIntegral verifyCases( { - def success[T](v: (T, (T, (T, (T, T))))) = Expected(Success(v), 39654, costArithOps(SByte)) + def success[T](v: (T, (T, (T, (T, T))))) = Expected(Success(v), 39654, arithOpsCostDetails(SByte), 1808) Seq( ((-128.toByte, -128.toByte), Expected(new ArithmeticException("Byte overflow"))), ((-128.toByte, 0.toByte), Expected(new ArithmeticException("/ by zero"))), @@ -955,20 +904,27 @@ class SigmaDslSpecification extends SigmaDslTesting )) } - def swapArgs[A](cases: Seq[((A, A), Expected[Boolean])], cost: Int, newCost: CostDetails) = + def swapArgs[A](cases: Seq[((A, A), Expected[Boolean])], cost: Int, newCostDetails: CostDetails) = cases.map { case ((x, y), res) => - ((y, x), Expected(res.value, cost, newCost)) + ((y, x), Expected(res.value, cost, newCostDetails, 1788)) } - def newCasesFrom[A, R](cases: Seq[(A, A)])(getExpectedRes: (A, A) => R, cost: Int) = + def newCasesFrom[A, R]( + cases: Seq[(A, A)] + )( + getExpectedRes: (A, A) => R, + cost: Int, + newDetails: CostDetails, + newCost: Int + ) = cases.map { case (x, y) => - ((x, y), Expected(Success(getExpectedRes(x, y)), cost = cost)) + ((x, y), Expected(Success(getExpectedRes(x, y)), cost = cost, newDetails, newCost)) } def newCasesFrom2[A, R](cases: Seq[(A, A)]) - (getExpectedRes: (A, A) => R, cost: Int, newCost: CostDetails) = + (getExpectedRes: (A, A) => R, cost: Int, newCostDetails: CostDetails) = cases.map { case (x, y) => - ((x, y), Expected(Success(getExpectedRes(x, y)), cost = cost, expectedDetails = newCost)) + ((x, y), Expected(Success(getExpectedRes(x, y)), cost = cost, expectedDetails = newCostDetails, expectedNewCost = 1786)) } def verifyOp[A: Ordering: Arbitrary] @@ -997,82 +953,11 @@ class SigmaDslSpecification extends SigmaDslTesting preGeneratedSamples = Some(sampled.samples)) } - def costLT(tpe: SType) = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - TypeBasedCostItem(LT, tpe) - ) - ) - def costGT(tpe: SType) = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - TypeBasedCostItem(GT, tpe) - ) - ) - def costNEQ(neqCost: Seq[CostItem]) = { - val trace = Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(SelectField) - ) ++ neqCost - CostDetails(trace) - } - val constNeqCost: Seq[CostItem] = Array[CostItem]() - - def costLE(tpe: SType) = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - TypeBasedCostItem(LE, tpe) - ) - ) - def costGE(tpe: SType) = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - TypeBasedCostItem(GE, tpe) - ) - ) + val constNeqCost: Seq[CostItem] = Array[CostItem](FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3)))) property("Byte LT, GT, NEQ") { val o = ExactOrdering.ByteIsExactOrdering - def expect(v: Boolean) = Expected(Success(v), 36328, costLT(SByte)) + def expect(v: Boolean) = Expected(Success(v), 36328, binaryRelationCostDetails(LT, SByte), 1788) val LT_cases: Seq[((Byte, Byte), Expected[Boolean])] = Seq( (-128.toByte, -128.toByte) -> expect(false), (-128.toByte, -127.toByte) -> expect(true), @@ -1113,16 +998,16 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LT_cases, "<", LT.apply)(_ < _) verifyOp( - swapArgs(LT_cases, cost = 36342, newCost = costGT(SByte)), + swapArgs(LT_cases, cost = 36342, newCostDetails = binaryRelationCostDetails(GT, SByte)), ">", GT.apply)(_ > _) - val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCost = costNEQ(constNeqCost)) + val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCostDetails = costNEQ(constNeqCost)) verifyOp(neqCases, "!=", NEQ.apply)(_ != _) } property("Byte LE, GE") { val o = ExactOrdering.ByteIsExactOrdering - def expect(v: Boolean) = Expected(Success(v), 36337, costLE(SByte)) + def expect(v: Boolean) = Expected(Success(v), 36337, binaryRelationCostDetails(LE, SByte), 1788) val LE_cases: Seq[((Byte, Byte), Expected[Boolean])] = Seq( (-128.toByte, -128.toByte) -> expect(true), (-128.toByte, -127.toByte) -> expect(true), @@ -1164,7 +1049,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LE_cases, "<=", LE.apply)(_ <= _) verifyOp( - swapArgs(LE_cases, cost = 36336, newCost = costGE(SByte)), + swapArgs(LE_cases, cost = 36336, newCostDetails = binaryRelationCostDetails(GE, SByte)), ">=", GE.apply)(_ >= _) } @@ -1199,7 +1084,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35976, costDowncast) + def success[T](v: T) = Expected(Success(v), 35976, downcastCostDetails(SByte), 1784) Seq( (Short.MinValue, Expected(new ArithmeticException("Byte overflow"))), (-21626.toShort, Expected(new ArithmeticException("Byte overflow"))), @@ -1218,7 +1103,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35798, costIdentity) + def success[T](v: T) = Expected(Success(v), 35798, TracedCost(traceBase), 1783) Seq( (-32768.toShort, success(-32768.toShort)), (-27798.toShort, success(-27798.toShort)), @@ -1235,7 +1120,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35902, costUpcast) + def success[T](v: T) = Expected(Success(v), 35902, upcastCostDetails(SInt), 1784) Seq( (-32768.toShort, success(-32768)), (-21064.toShort, success(-21064)), @@ -1252,7 +1137,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35902, costUpcast) + def success[T](v: T) = Expected(Success(v), 35902, upcastCostDetails(SLong), 1784) Seq( (-32768.toShort, success(-32768L)), (-23408.toShort, success(-23408L)), @@ -1269,7 +1154,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success(v: BigInt) = Expected(Success(v), 35932, costUpcast) + def success(v: BigInt) = Expected(Success(v), 35932, upcastCostDetails(SBigInt), 1787) Seq( (-32768.toShort, success(CBigInt(new BigInteger("-8000", 16)))), (-26248.toShort, success(CBigInt(new BigInteger("-6688", 16)))), @@ -1287,7 +1172,7 @@ class SigmaDslSpecification extends SigmaDslTesting val n = ExactIntegral.ShortIsExactIntegral verifyCases( { - def success[T](v: T) = Expected(Success(v), 39654, costArithOps(SShort)) + def success[T](v: T) = Expected(Success(v), 39654, arithOpsCostDetails(SShort), 1808) Seq( ((-32768.toShort, 1.toShort), Expected(new ArithmeticException("Short overflow"))), ((-32768.toShort, 4006.toShort), Expected(new ArithmeticException("Short overflow"))), @@ -1379,7 +1264,7 @@ class SigmaDslSpecification extends SigmaDslTesting property("Short LT, GT, NEQ") { val o = ExactOrdering.ShortIsExactOrdering - def expect(v: Boolean) = Expected(Success(v), 36328, costLT(SShort)) + def expect(v: Boolean) = Expected(Success(v), 36328, binaryRelationCostDetails(LT, SShort), 1788) val LT_cases: Seq[((Short, Short), Expected[Boolean])] = Seq( (Short.MinValue, Short.MinValue) -> expect(false), (Short.MinValue, (Short.MinValue + 1).toShort) -> expect(true), @@ -1419,15 +1304,15 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LT_cases, "<", LT.apply)(_ < _) - verifyOp(swapArgs(LT_cases, cost = 36342, costGT(SShort)), ">", GT.apply)(_ > _) + verifyOp(swapArgs(LT_cases, cost = 36342, newCostDetails = binaryRelationCostDetails(GT, SShort)), ">", GT.apply)(_ > _) - val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCost = costNEQ(constNeqCost)) + val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCostDetails = costNEQ(constNeqCost)) verifyOp(neqCases, "!=", NEQ.apply)(_ != _) } property("Short LE, GE") { val o = ExactOrdering.ShortIsExactOrdering - def expect(v: Boolean) = Expected(Success(v), 36337, costLE(SShort)) + def expect(v: Boolean) = Expected(Success(v), 36337, binaryRelationCostDetails(LE, SShort), 1788) val LE_cases: Seq[((Short, Short), Expected[Boolean])] = Seq( (Short.MinValue, Short.MinValue) -> expect(true), (Short.MinValue, (Short.MinValue + 1).toShort) -> expect(true), @@ -1469,7 +1354,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LE_cases, "<=", LE.apply)(_ <= _) verifyOp( - swapArgs(LE_cases, cost = 36336, newCost = costGE(SShort)), + swapArgs(LE_cases, cost = 36336, newCostDetails = binaryRelationCostDetails(GE, SShort)), ">=", GE.apply)(_ >= _) } @@ -1503,7 +1388,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35976, costDowncast) + def success[T](v: T) = Expected(Success(v), 35976, downcastCostDetails(SByte), 1784) Seq( (Int.MinValue, Expected(new ArithmeticException("Byte overflow"))), (-2014394379, Expected(new ArithmeticException("Byte overflow"))), @@ -1522,7 +1407,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35976, costDowncast) + def success[T](v: T) = Expected(Success(v), 35976, downcastCostDetails(SShort), 1784) Seq( (Int.MinValue, Expected(new ArithmeticException("Short overflow"))), (Short.MinValue - 1, Expected(new ArithmeticException("Short overflow"))), @@ -1541,7 +1426,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35798, costIdentity) + def success[T](v: T) = Expected(Success(v), 35798, TracedCost(traceBase), 1783) Seq( (Int.MinValue, success(Int.MinValue)), (-1, success(-1)), @@ -1556,7 +1441,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35902, costUpcast) + def success[T](v: T) = Expected(Success(v), 35902, upcastCostDetails(SLong), 1784) Seq( (Int.MinValue, success(Int.MinValue.toLong)), (-1, success(-1L)), @@ -1571,7 +1456,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success(v: BigInt) = Expected(Success(v), 35932, costUpcast) + def success(v: BigInt) = Expected(Success(v), 35932, upcastCostDetails(SBigInt), 1787) Seq( (Int.MinValue, success(CBigInt(new BigInteger("-80000000", 16)))), (-1937187314, success(CBigInt(new BigInteger("-737721f2", 16)))), @@ -1589,7 +1474,7 @@ class SigmaDslSpecification extends SigmaDslTesting val n = ExactNumeric.IntIsExactNumeric verifyCases( { - def success[T](v: T) = Expected(Success(v), 39654, costArithOps(SInt)) + def success[T](v: T) = Expected(Success(v), 39654, arithOpsCostDetails(SInt), 1808) Seq( ((Int.MinValue, 449583993), Expected(new ArithmeticException("integer overflow"))), ((-1589633733, 2147483647), Expected(new ArithmeticException("integer overflow"))), @@ -1681,7 +1566,7 @@ class SigmaDslSpecification extends SigmaDslTesting property("Int LT, GT, NEQ") { val o = ExactOrdering.IntIsExactOrdering - def expect(v: Boolean) = Expected(Success(v), 36328, costLT(SInt)) + def expect(v: Boolean) = Expected(Success(v), 36328, binaryRelationCostDetails(LT, SInt), 1788) val LT_cases: Seq[((Int, Int), Expected[Boolean])] = Seq( (Int.MinValue, Int.MinValue) -> expect(false), (Int.MinValue, (Int.MinValue + 1).toInt) -> expect(true), @@ -1722,16 +1607,16 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LT_cases, "<", LT.apply)(_ < _) verifyOp( - swapArgs(LT_cases, cost = 36342, newCost = costGT(SInt)), + swapArgs(LT_cases, cost = 36342, newCostDetails = binaryRelationCostDetails(GT, SInt)), ">", GT.apply)(_ > _) - val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCost = costNEQ(constNeqCost)) + val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCostDetails = costNEQ(constNeqCost)) verifyOp(neqCases, "!=", NEQ.apply)(_ != _) } property("Int LE, GE") { val o = ExactOrdering.IntIsExactOrdering - def expect(v: Boolean) = Expected(Success(v), 36337, costLE(SInt)) + def expect(v: Boolean) = Expected(Success(v), 36337, binaryRelationCostDetails(LE, SInt), 1788) val LE_cases: Seq[((Int, Int), Expected[Boolean])] = Seq( (Int.MinValue, Int.MinValue) -> expect(true), (Int.MinValue, (Int.MinValue + 1).toInt) -> expect(true), @@ -1773,7 +1658,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LE_cases, "<=", LE.apply)(_ <= _) verifyOp( - swapArgs(LE_cases, cost = 36336, newCost = costGE(SInt)), + swapArgs(LE_cases, cost = 36336, newCostDetails = binaryRelationCostDetails(GE, SInt)), ">=", GE.apply)(_ >= _) } @@ -1800,13 +1685,17 @@ class SigmaDslSpecification extends SigmaDslTesting } } - property("Long methods equivalence") { - SLong.upcast(0L) shouldBe 0L // boundary test case - SLong.downcast(0L) shouldBe 0L // boundary test case + property("Long downcast and upcast identity") { + forAll { x: Long => + SLong.upcast(x) shouldBe x // boundary test case + SLong.downcast(x) shouldBe x // boundary test case + } + } + property("Long.toByte method") { verifyCases( { - def success[T](v: T) = Expected(Success(v), 35976, costDowncast) + def success[T](v: T) = Expected(Success(v), 35976, downcastCostDetails(SByte), 1784) Seq( (Long.MinValue, Expected(new ArithmeticException("Byte overflow"))), (Byte.MinValue.toLong - 1, Expected(new ArithmeticException("Byte overflow"))), @@ -1822,10 +1711,12 @@ class SigmaDslSpecification extends SigmaDslTesting existingFeature((x: Long) => x.toByteExact, "{ (x: Long) => x.toByte }", FuncValue(Vector((1, SLong)), Downcast(ValUse(1, SLong), SByte)))) + } + property("Long.toShort method") { verifyCases( { - def success[T](v: T) = Expected(Success(v), 35976, costDowncast) + def success[T](v: T) = Expected(Success(v), 35976, downcastCostDetails(SShort), 1784) Seq( (Long.MinValue, Expected(new ArithmeticException("Short overflow"))), (Short.MinValue.toLong - 1, Expected(new ArithmeticException("Short overflow"))), @@ -1841,10 +1732,12 @@ class SigmaDslSpecification extends SigmaDslTesting existingFeature((x: Long) => x.toShortExact, "{ (x: Long) => x.toShort }", FuncValue(Vector((1, SLong)), Downcast(ValUse(1, SLong), SShort)))) + } + property("Long.toInt method") { verifyCases( { - def success[T](v: T) = Expected(Success(v), 35976, costDowncast) + def success[T](v: T) = Expected(Success(v), 35976, downcastCostDetails(SInt), 1784) Seq( (Long.MinValue, Expected(new ArithmeticException("Int overflow"))), (Int.MinValue.toLong - 1, Expected(new ArithmeticException("Int overflow"))), @@ -1860,10 +1753,12 @@ class SigmaDslSpecification extends SigmaDslTesting existingFeature((x: Long) => x.toIntExact, "{ (x: Long) => x.toInt }", FuncValue(Vector((1, SLong)), Downcast(ValUse(1, SLong), SInt)))) + } + property("Long.toLong method") { verifyCases( { - def success[T](v: T) = Expected(Success(v), 35798, costIdentity) + def success[T](v: T) = Expected(Success(v), 35798, TracedCost(traceBase), 1783) Seq( (Long.MinValue, success(Long.MinValue)), (-1L, success(-1L)), @@ -1875,10 +1770,12 @@ class SigmaDslSpecification extends SigmaDslTesting existingFeature((x: Long) => x.toLong, "{ (x: Long) => x.toLong }", FuncValue(Vector((1, SLong)), ValUse(1, SLong)))) + } + property("Long.toBigInt method") { verifyCases( { - def success(v: BigInt) = Expected(Success(v), 35932, costUpcast) + def success(v: BigInt) = Expected(Success(v), 35932, upcastCostDetails(SBigInt), 1787) Seq( (Long.MinValue, success(CBigInt(new BigInteger("-8000000000000000", 16)))), (-1074651039980347209L, success(CBigInt(new BigInteger("-ee9ed6d57885f49", 16)))), @@ -1892,11 +1789,14 @@ class SigmaDslSpecification extends SigmaDslTesting existingFeature((x: Long) => x.toBigInt, "{ (x: Long) => x.toBigInt }", FuncValue(Vector((1, SLong)), Upcast(ValUse(1, SLong), SBigInt)))) + } + + property("Long methods equivalence") { val n = ExactNumeric.LongIsExactNumeric verifyCases( { - def success[T](v: T) = Expected(Success(v), 39654, costArithOps(SLong)) + def success[T](v: T) = Expected(Success(v), 39654, arithOpsCostDetails(SLong), 1808) Seq( ((Long.MinValue, -4677100190307931395L), Expected(new ArithmeticException("long overflow"))), ((Long.MinValue, -1L), Expected(new ArithmeticException("long overflow"))), @@ -1986,7 +1886,7 @@ class SigmaDslSpecification extends SigmaDslTesting property("Long LT, GT, NEQ") { val o = ExactOrdering.LongIsExactOrdering - def expect(v: Boolean) = Expected(Success(v), 36328, costLT(SLong)) + def expect(v: Boolean) = Expected(Success(v), 36328, binaryRelationCostDetails(LT, SLong), 1788) val LT_cases: Seq[((Long, Long), Expected[Boolean])] = Seq( (Long.MinValue, Long.MinValue) -> expect(false), (Long.MinValue, (Long.MinValue + 1).toLong) -> expect(true), @@ -2027,16 +1927,16 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LT_cases, "<", LT.apply)(_ < _) verifyOp( - swapArgs(LT_cases, cost = 36342, newCost = costGT(SLong)), + swapArgs(LT_cases, cost = 36342, newCostDetails = binaryRelationCostDetails(GT, SLong)), ">", GT.apply)(_ > _) - val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCost = costNEQ(constNeqCost)) + val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCostDetails = costNEQ(constNeqCost)) verifyOp(neqCases, "!=", NEQ.apply)(_ != _) } property("Long LE, GE") { val o = ExactOrdering.LongIsExactOrdering - def expect(v: Boolean) = Expected(Success(v), 36337, costLE(SLong)) + def expect(v: Boolean) = Expected(Success(v), 36337, binaryRelationCostDetails(LE, SLong), 1788) val LE_cases: Seq[((Long, Long), Expected[Boolean])] = Seq( (Long.MinValue, Long.MinValue) -> expect(true), (Long.MinValue, (Long.MinValue + 1).toLong) -> expect(true), @@ -2078,7 +1978,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LE_cases, "<=", LE.apply)(_ <= _) verifyOp( - swapArgs(LE_cases, cost = 36336, newCost = costGE(SLong)), + swapArgs(LE_cases, cost = 36336, newCostDetails = binaryRelationCostDetails(GE, SLong)), ">=", GE.apply)(_ >= _) } @@ -2109,7 +2009,7 @@ class SigmaDslSpecification extends SigmaDslTesting property("BigInt methods equivalence") { verifyCases( { - def success(v: BigInt) = Expected(Success(v), 35798, costIdentity) + def success(v: BigInt) = Expected(Success(v), 35798, TracedCost(traceBase), 1784) Seq( (CBigInt(new BigInteger("-85102d7f884ca0e8f56193b46133acaf7e4681e1757d03f191ae4f445c8e0", 16)), success( CBigInt(new BigInteger("-85102d7f884ca0e8f56193b46133acaf7e4681e1757d03f191ae4f445c8e0", 16)) @@ -2131,40 +2031,8 @@ class SigmaDslSpecification extends SigmaDslTesting val n = NumericOps.BigIntIsExactIntegral verifyCases( { - val costArithOps = CostDetails( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Plus, SBigInt), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Minus, SBigInt), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Multiply, SBigInt), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Division, SBigInt), - FixedCostItem(ValUse), - FixedCostItem(ValUse), - TypeBasedCostItem(ArithOp.Modulo, SBigInt), - FixedCostItem(Tuple), - FixedCostItem(Tuple), - FixedCostItem(Tuple), - FixedCostItem(Tuple) - ) - ) def success(v: (BigInt, (BigInt, (BigInt, (BigInt, BigInt))))) = - Expected(Success(v), 39774, costArithOps) + Expected(Success(v), 39774, arithOpsCostDetails(SBigInt), 1813) Seq( ((CBigInt(new BigInteger("-8683d1cd99d5fcf0e6eff6295c285c36526190e13dbde008c49e5ae6fddc1c", 16)), CBigInt(new BigInteger("-2ef55db3f245feddacf0182e299dd", 16))), @@ -2288,7 +2156,7 @@ class SigmaDslSpecification extends SigmaDslTesting property("BigInt LT, GT, NEQ") { val o = NumericOps.BigIntIsExactOrdering - def expect(v: Boolean) = Expected(Success(v), 36328, costLT(SBigInt)) + def expect(v: Boolean) = Expected(Success(v), 36328, binaryRelationCostDetails(LT, SBigInt), 1788) val LT_cases: Seq[((BigInt, BigInt), Expected[Boolean])] = Seq( (BigIntMinValue, BigIntMinValue) -> expect(false), @@ -2332,10 +2200,11 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LT_cases, "<", LT.apply)(o.lt(_, _)) verifyOp( - swapArgs(LT_cases, cost = 36342, newCost = costGT(SBigInt)), + swapArgs(LT_cases, cost = 36342, newCostDetails = binaryRelationCostDetails(GT, SBigInt)), ">", GT.apply)(o.gt(_, _)) - val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCost = costNEQ(constNeqCost)) + val constBigIntCost = Array[CostItem](FixedCostItem(NamedDesc("EQ_BigInt"), FixedCost(JitCost(5)))) + val neqCases = newCasesFrom2(LT_cases.map(_._1))(_ != _, cost = 36337, newCostDetails = costNEQ(constBigIntCost)) verifyOp(neqCases, "!=", NEQ.apply)(_ != _) } @@ -2346,7 +2215,7 @@ class SigmaDslSpecification extends SigmaDslTesting val BigIntMaxValue = CBigInt(new BigInteger("7F" + "ff" * 31, 16)) val BigIntOverlimit = CBigInt(new BigInteger("7F" + "ff" * 33, 16)) - def expect(v: Boolean) = Expected(Success(v), 36337, costLE(SBigInt)) + def expect(v: Boolean) = Expected(Success(v), 36337, binaryRelationCostDetails(LE, SBigInt), 1788) val LE_cases: Seq[((BigInt, BigInt), Expected[Boolean])] = Seq( (BigIntMinValue, BigIntMinValue) -> expect(true), @@ -2391,7 +2260,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyOp(LE_cases, "<=", LE.apply)(o.lteq(_, _)) verifyOp( - swapArgs(LE_cases, cost = 36336, newCost = costGE(SBigInt)), + swapArgs(LE_cases, cost = 36336, newCostDetails = binaryRelationCostDetails(GE, SBigInt)), ">=", GE.apply)(o.gteq(_, _)) } @@ -2454,87 +2323,237 @@ class SigmaDslSpecification extends SigmaDslTesting * @param cost the expected cost of `verify` (the same for all cases) */ def verifyNeq[A: Ordering: Arbitrary: RType] - (x: A, y: A, cost: Int, neqCost: Seq[CostItem] = mutable.WrappedArray.empty) + (x: A, y: A, cost: Int, neqCost: Seq[CostItem] = mutable.WrappedArray.empty, newCost: Int) (copy: A => A, generateCases: Boolean = true) (implicit sampled: Sampled[(A, A)], evalSettings: EvalSettings) = { val copied_x = copy(x) - val newCost = if (neqCost.isEmpty) CostDetails.ZeroCost else costNEQ(neqCost) - def expected(v: Boolean) = Expected(Success(v), cost, newCost) + val newCostDetails = if (neqCost.isEmpty) CostDetails.ZeroCost else costNEQ(neqCost) + def expected(v: Boolean) = Expected(Success(v), cost, newCostDetails, newCost) + def expectedNoCost(v: Boolean) = Expected(Success(v), cost, CostDetails.ZeroCost) verifyOp(Seq( - (x, x) -> expected(false), - (x, copied_x) -> expected(false), - (copied_x, x) -> expected(false), - (x, y) -> expected(true), - (y, x) -> expected(true) + (x, y) -> expected(true), // check cost only for this test case, because the trace depends in x and y + (x, x) -> expectedNoCost(false), // and don't check for others + (x, copied_x) -> expectedNoCost(false), + (copied_x, x) -> expectedNoCost(false), + (y, x) -> expectedNoCost(true) ), "!=", NEQ.apply)(_ != _, generateCases) } property("NEQ of pre-defined types") { - verifyNeq(ge1, ge2, 36337, constNeqCost)(_.asInstanceOf[CGroupElement].copy()) - verifyNeq(t1, t2, 36337, constNeqCost)(_.asInstanceOf[CAvlTree].copy()) - verifyNeq(b1, b2, 36417, - Array[CostItem]())(_.asInstanceOf[CostingBox].copy()) - verifyNeq(preH1, preH2, 36337, constNeqCost)(_.asInstanceOf[CPreHeader].copy()) - verifyNeq(h1, h2, 36337, constNeqCost)(_.asInstanceOf[CHeader].copy()) + verifyNeq(ge1, ge2, 36337, Array[CostItem](FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172)))), 1803)(_.asInstanceOf[CGroupElement].copy()) + verifyNeq(t1, t2, 36337, Array[CostItem](FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6)))), 1787)(_.asInstanceOf[CAvlTree].copy()) + verifyNeq(b1, b2, 36417, Array[CostItem](), 1787)(_.asInstanceOf[CostingBox].copy()) + verifyNeq(preH1, preH2, 36337, Array[CostItem](FixedCostItem(NamedDesc("EQ_PreHeader"), FixedCost(JitCost(4)))), 1786)(_.asInstanceOf[CPreHeader].copy()) + verifyNeq(h1, h2, 36337, Array[CostItem](FixedCostItem(NamedDesc("EQ_Header"), FixedCost(JitCost(6)))), 1787)(_.asInstanceOf[CHeader].copy()) } property("NEQ of tuples of numerics") { - verifyNeq((0.toByte, 1.toByte), (1.toByte, 1.toByte), 36337, constNeqCost)(_.copy()) - verifyNeq((0.toShort, 1.toByte), (1.toShort, 1.toByte), 36337, constNeqCost)(_.copy()) - verifyNeq((0, 1.toByte), (1, 1.toByte), 36337, constNeqCost)(_.copy()) - verifyNeq((0.toLong, 1.toByte), (1.toLong, 1.toByte), 36337, constNeqCost)(_.copy()) - verifyNeq((0.toBigInt, 1.toByte), (1.toBigInt, 1.toByte), 36337, constNeqCost)(_.copy()) + val tuplesNeqCost = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))) + ) + verifyNeq((0.toByte, 1.toByte), (1.toByte, 1.toByte), 36337, tuplesNeqCost, 1787)(_.copy()) + verifyNeq((0.toShort, 1.toByte), (1.toShort, 1.toByte), 36337, tuplesNeqCost, 1787)(_.copy()) + verifyNeq((0, 1.toByte), (1, 1.toByte), 36337, tuplesNeqCost, 1787)(_.copy()) + verifyNeq((0.toLong, 1.toByte), (1.toLong, 1.toByte), 36337, tuplesNeqCost, 1787)(_.copy()) + verifyNeq((0.toBigInt, 1.toByte), (1.toBigInt, 1.toByte), 36337, Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_BigInt"), FixedCost(JitCost(5))) + ), 1787)(_.copy()) } property("NEQ of tuples of pre-defined types") { - verifyNeq((ge1, ge1), (ge1, ge2), 36337, constNeqCost)(_.copy()) - verifyNeq((t1, t1), (t1, t2), 36337, constNeqCost)(_.copy()) - verifyNeq((b1, b1), (b1, b2), - cost = 36497, - neqCost = Array[CostItem]() - )(_.copy()) - verifyNeq((preH1, preH1), (preH1, preH2), 36337, constNeqCost)(_.copy()) - verifyNeq((h1, h1), (h1, h2), 36337, constNeqCost)(_.copy()) - } + val groupNeqCost = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))) + ) + verifyNeq((ge1, ge1), (ge1, ge2), 36337, groupNeqCost, 1821)(_.copy()) + + val treeNeqCost = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))) + ) + verifyNeq((t1, t1), (t1, t2), 36337, treeNeqCost, 1788)(_.copy()) + verifyNeq((b1, b1), (b1, b2), 36497, Array[CostItem](), 1788)(_.copy()) + + val preHeaderNeqCost = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_PreHeader"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_PreHeader"), FixedCost(JitCost(4))) + ) + verifyNeq((preH1, preH1), (preH1, preH2), 36337, preHeaderNeqCost, 1787)(_.copy()) + + val headerNeqCost = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Header"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Header"), FixedCost(JitCost(6))) + ) + verifyNeq((h1, h1), (h1, h2), 36337, headerNeqCost, 1788)(_.copy()) + } + property("NEQ of nested tuples") { - verifyNeq((ge1, (t1, t1)), (ge1, (t1, t2)), 36337)(_.copy()) - verifyNeq((ge1, (t1, (b1, b1))), (ge1, (t1, (b1, b2))), 36497)(_.copy()) - verifyNeq((ge1, (t1, (b1, (preH1, preH1)))), (ge1, (t1, (b1, (preH1, preH2)))), 36417)(_.copy()) - verifyNeq((ge1, (t1, (b1, (preH1, (h1, h1))))), (ge1, (t1, (b1, (preH1, (h1, h2))))), 36427)(_.copy()) + val nestedTuplesNeqCost1 = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))) + ) + val nestedTuplesNeqCost2 = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Box"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Box"), FixedCost(JitCost(6))) + ) + val nestedTuplesNeqCost3 = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Box"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_PreHeader"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_PreHeader"), FixedCost(JitCost(4))) + ) + val nestedTuplesNeqCost4 = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Box"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_PreHeader"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Header"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Header"), FixedCost(JitCost(6))) + ) + val nestedTuplesNeqCost5 = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))) + ) + val nestedTuplesNeqCost6 = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Box"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Box"), FixedCost(JitCost(6))) + ) + val nestedTuplesNeqCost7 = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Box"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_PreHeader"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_PreHeader"), FixedCost(JitCost(4))) + ) + val nestedTuplesNeqCost8 = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Box"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_PreHeader"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Header"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("EQ_Header"), FixedCost(JitCost(6))) + ) + verifyNeq((ge1, (t1, t1)), (ge1, (t1, t2)), 36337, nestedTuplesNeqCost1, 1805)(_.copy()) + verifyNeq((ge1, (t1, (b1, b1))), (ge1, (t1, (b1, b2))), 36497, nestedTuplesNeqCost2, 1806)(_.copy()) + verifyNeq((ge1, (t1, (b1, (preH1, preH1)))), (ge1, (t1, (b1, (preH1, preH2)))), 36417, nestedTuplesNeqCost3, 1807)(_.copy()) + verifyNeq((ge1, (t1, (b1, (preH1, (h1, h1))))), (ge1, (t1, (b1, (preH1, (h1, h2))))), 36427, nestedTuplesNeqCost4, 1808)(_.copy()) - verifyNeq(((ge1, t1), t1), ((ge1, t1), t2), 36337)(_.copy()) - verifyNeq((((ge1, t1), b1), b1), (((ge1, t1), b1), b2), 36497)(_.copy()) - verifyNeq((((ge1, t1), b1), (preH1, preH1)), (((ge1, t1), b1), (preH1, preH2)), 36417)(_.copy()) - verifyNeq((((ge1, t1), b1), (preH1, (h1, h1))), (((ge1, t1), b1), (preH1, (h1, h2))), 36427)(_.copy()) + verifyNeq(((ge1, t1), t1), ((ge1, t1), t2), 36337, nestedTuplesNeqCost5, 1805)(_.copy()) + verifyNeq((((ge1, t1), b1), b1), (((ge1, t1), b1), b2), 36497, nestedTuplesNeqCost6, 1806)(_.copy()) + verifyNeq((((ge1, t1), b1), (preH1, preH1)), (((ge1, t1), b1), (preH1, preH2)), 36417, nestedTuplesNeqCost7, 1807)(_.copy()) + verifyNeq((((ge1, t1), b1), (preH1, (h1, h1))), (((ge1, t1), b1), (preH1, (h1, h2))), 36427, nestedTuplesNeqCost8, 1808)(_.copy()) } property("NEQ of collections of pre-defined types") { + val collNeqCost1 = Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))) + ) + val collNeqCost2 = Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_Box"), PerItemCost(JitCost(15), JitCost(5), 1), 0) + ) implicit val evalSettings = suite.evalSettings.copy(isMeasureOperationTime = false) - verifyNeq(Coll[Byte](), Coll(1.toByte), 36337)(cloneColl(_)) - verifyNeq(Coll[Byte](0, 1), Coll(1.toByte, 1.toByte), 36337)(cloneColl(_)) + verifyNeq(Coll[Byte](), Coll(1.toByte), 36337, collNeqCost1, 1786)(cloneColl(_)) + verifyNeq(Coll[Byte](0, 1), Coll(1.toByte, 1.toByte), 36337, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_Byte"), PerItemCost(JitCost(15), JitCost(2), 128), 1)), + 1788 + )(cloneColl(_)) - verifyNeq(Coll[Short](), Coll(1.toShort), 36337)(cloneColl(_)) - verifyNeq(Coll[Short](0), Coll(1.toShort), 36337)(cloneColl(_)) + verifyNeq(Coll[Short](), Coll(1.toShort), 36337, collNeqCost1, 1786)(cloneColl(_)) + verifyNeq(Coll[Short](0), Coll(1.toShort), 36337, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_Short"), PerItemCost(JitCost(15), JitCost(2), 96), 1)), + 1788 + )(cloneColl(_)) - verifyNeq(Coll[Int](), Coll(1), 36337)(cloneColl(_)) - verifyNeq(Coll[Int](0), Coll(1), 36337)(cloneColl(_)) + verifyNeq(Coll[Int](), Coll(1), 36337, collNeqCost1, 1786)(cloneColl(_)) + verifyNeq(Coll[Int](0), Coll(1), 36337, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_Int"), PerItemCost(JitCost(15), JitCost(2), 64), 1)), + 1788 + )(cloneColl(_)) - verifyNeq(Coll[Long](), Coll(1.toLong), 36337)(cloneColl(_)) - verifyNeq(Coll[Long](0), Coll(1.toLong), 36337)(cloneColl(_)) + verifyNeq(Coll[Long](), Coll(1.toLong), 36337, collNeqCost1, 1786)(cloneColl(_)) + verifyNeq(Coll[Long](0), Coll(1.toLong), 36337, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_Long"), PerItemCost(JitCost(15), JitCost(2), 48), 1)), + 1788 + )(cloneColl(_)) prepareSamples[Coll[BigInt]] - verifyNeq(Coll[BigInt](), Coll(1.toBigInt), 36337)(cloneColl(_)) - verifyNeq(Coll[BigInt](0.toBigInt), Coll(1.toBigInt), 36337)(cloneColl(_)) + verifyNeq(Coll[BigInt](), Coll(1.toBigInt), 36337, collNeqCost1, 1786)(cloneColl(_)) + verifyNeq(Coll[BigInt](0.toBigInt), Coll(1.toBigInt), 36337, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_BigInt"), PerItemCost(JitCost(15), JitCost(7), 5), 1)), + 1788 + )(cloneColl(_)) prepareSamples[Coll[GroupElement]] - verifyNeq(Coll[GroupElement](), Coll(ge1), 36337)(cloneColl(_)) - verifyNeq(Coll[GroupElement](ge1), Coll(ge2), 36337)(cloneColl(_)) + verifyNeq(Coll[GroupElement](), Coll(ge1), 36337, collNeqCost1, 1786)(cloneColl(_)) + verifyNeq(Coll[GroupElement](ge1), Coll(ge2), 36337, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_GroupElement"), PerItemCost(JitCost(15), JitCost(5), 1), 1)), + 1788 + )(cloneColl(_)) prepareSamples[Coll[AvlTree]] - verifyNeq(Coll[AvlTree](), Coll(t1), 36337)(cloneColl(_)) - verifyNeq(Coll[AvlTree](t1), Coll(t2), 36337)(cloneColl(_)) + verifyNeq(Coll[AvlTree](), Coll(t1), 36337, collNeqCost1, 1786)(cloneColl(_)) + verifyNeq(Coll[AvlTree](t1), Coll(t2), 36337, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_AvlTree"), PerItemCost(JitCost(15), JitCost(5), 2), 1)), + 1788 + )(cloneColl(_)) { // since SBox.isConstantSize = false, the cost is different among cases prepareSamples[Coll[AvlTree]] @@ -2542,24 +2561,39 @@ class SigmaDslSpecification extends SigmaDslTesting val y = Coll(b1) val copied_x = cloneColl(x) verifyOp(Seq( - (x, x) -> Expected(Success(false), 36337), - (x, copied_x) -> Expected(Success(false), 36337), - (copied_x, x) -> Expected(Success(false), 36337), - (x, y) -> Expected(Success(true), 36377), - (y, x) -> Expected(Success(true), 36377) + (x, x) -> Expected(Success(false), 36337, costNEQ(collNeqCost2), 1788), + (x, copied_x) -> Expected(Success(false), 36337, costNEQ(collNeqCost2), 1788), + (copied_x, x) -> Expected(Success(false), 36337, costNEQ(collNeqCost2), 1788), + (x, y) -> Expected(Success(true), 36377, costNEQ(collNeqCost1), 1786), + (y, x) -> Expected(Success(true), 36377, costNEQ(collNeqCost1), 1786) ), "!=", NEQ.apply)(_ != _, generateCases = false) - verifyNeq(Coll[Box](b1), Coll(b2), 36417)(cloneColl(_), generateCases = false) + verifyNeq(Coll[Box](b1), Coll(b2), 36417, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_Box"), PerItemCost(JitCost(15), JitCost(5), 1), 1)), + 1788 + )(cloneColl(_), generateCases = false) } prepareSamples[Coll[PreHeader]] - verifyNeq(Coll[PreHeader](), Coll(preH1), 36337)(cloneColl(_)) - verifyNeq(Coll[PreHeader](preH1), Coll(preH2), 36337)(cloneColl(_)) + verifyNeq(Coll[PreHeader](), Coll(preH1), 36337, collNeqCost1, 1786)(cloneColl(_)) + verifyNeq(Coll[PreHeader](preH1), Coll(preH2), 36337, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_PreHeader"), PerItemCost(JitCost(15), JitCost(3), 1), 1)), + 1788 + )(cloneColl(_)) prepareSamples[Coll[Header]] - verifyNeq(Coll[Header](), Coll(h1), 36337)(cloneColl(_)) - verifyNeq(Coll[Header](h1), Coll(h2), 36337)(cloneColl(_)) + verifyNeq(Coll[Header](), Coll(h1), 36337, collNeqCost1, 1786)(cloneColl(_)) + verifyNeq(Coll[Header](h1), Coll(h2), 36337, + Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_Header"), PerItemCost(JitCost(15), JitCost(5), 1), 1)), + 1788 + )(cloneColl(_)) } property("NEQ of nested collections and tuples") { @@ -2568,16 +2602,68 @@ class SigmaDslSpecification extends SigmaDslTesting prepareSamples[Coll[Coll[Int]]] prepareSamples[Coll[Coll[Int]]] - verifyNeq(Coll[Coll[Int]](), Coll(Coll[Int]()), 36337)(cloneColl(_)) - verifyNeq(Coll(Coll[Int]()), Coll(Coll[Int](1)), 36337)(cloneColl(_)) - verifyNeq(Coll(Coll[Int](1)), Coll(Coll[Int](2)), 36337)(cloneColl(_)) - verifyNeq(Coll(Coll[Int](1)), Coll(Coll[Int](1, 2)), 36337)(cloneColl(_)) + val nestedNeq1 = Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))) + ) + val nestedNeq2 = Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 1) + ) + val nestedNeq3 = Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + SeqCostItem(NamedDesc("EQ_COA_Int"), PerItemCost(JitCost(15), JitCost(2), 64), 1), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 1) + ) + verifyNeq(Coll[Coll[Int]](), Coll(Coll[Int]()), 36337, nestedNeq1, 1786)(cloneColl(_)) + verifyNeq(Coll(Coll[Int]()), Coll(Coll[Int](1)), 36337, nestedNeq2, 1787)(cloneColl(_)) + verifyNeq(Coll(Coll[Int](1)), Coll(Coll[Int](2)), 36337, nestedNeq3, 1789)(cloneColl(_)) + verifyNeq(Coll(Coll[Int](1)), Coll(Coll[Int](1, 2)), 36337, nestedNeq2, 1787)(cloneColl(_)) prepareSamples[Coll[(Int, BigInt)]] prepareSamples[Coll[Coll[(Int, BigInt)]]] - verifyNeq(Coll(Coll((1, 10.toBigInt))), Coll(Coll((1, 11.toBigInt))), 36337)(cloneColl(_)) - verifyNeq(Coll(Coll(Coll((1, 10.toBigInt)))), Coll(Coll(Coll((1, 11.toBigInt)))), 36337)(cloneColl(_)) + val nestedNeq4 = Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(NamedDesc("EQ_BigInt"), FixedCost(JitCost(5))), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 1), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 1) + ) + val nestedNeq5 = Array( + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(NamedDesc("EQ_BigInt"), FixedCost(JitCost(5))), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 1), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 1), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 1) + ) + val nestedNeq6 = Array( + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_AvlTree"), FixedCost(JitCost(6))), + FixedCostItem(NamedDesc("MatchType"), FixedCost(JitCost(1))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(NamedDesc("EQ_BigInt"), FixedCost(JitCost(5))), + FixedCostItem(NamedDesc("EQ_Tuple"), FixedCost(JitCost(4))), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(NamedDesc("EQ_BigInt"), FixedCost(JitCost(5))), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 2), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 1), + SeqCostItem(NamedDesc("EQ_Coll"), PerItemCost(JitCost(10), JitCost(2), 1), 1) + ) + verifyNeq(Coll(Coll((1, 10.toBigInt))), Coll(Coll((1, 11.toBigInt))), 36337, nestedNeq4, 1790)(cloneColl(_)) + verifyNeq(Coll(Coll(Coll((1, 10.toBigInt)))), Coll(Coll(Coll((1, 11.toBigInt)))), 36337, nestedNeq5, 1791)(cloneColl(_)) verifyNeq( (Coll( (Coll( @@ -2589,25 +2675,16 @@ class SigmaDslSpecification extends SigmaDslTesting (t1, Coll((1, 10.toBigInt), (1, 11.toBigInt))) ), ge1) ), preH1), - 36337)(x => (cloneColl(x._1), x._2)) + 36337, + nestedNeq6, + 1794 + )(x => (cloneColl(x._1), x._2)) } property("GroupElement.getEncoded equivalence") { verifyCases( { - val cost = TracedCost( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(PropertyCall), - MethodCallCostItem(TracedCost(Array(FixedCostItem(SGroupElement.GetEncodedMethod, FixedCost(JitCost(3)))))) - ) - ) - def success[T](v: T) = Expected(Success(v), 37905, cost) + def success[T](v: T) = Expected(Success(v), 37905, methodCostDetails(SGroupElement.GetEncodedMethod, 250), 1810) Seq( (ge1, success(Helpers.decodeBytes(ge1str))), (ge2, success(Helpers.decodeBytes(ge2str))), @@ -2629,21 +2706,16 @@ class SigmaDslSpecification extends SigmaDslTesting property("decodePoint(GroupElement.getEncoded) equivalence") { verifyCases( { - val cost = TracedCost( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val costDetails = TracedCost( + traceBase ++ Array( FixedCostItem(PropertyCall), - MethodCallCostItem(TracedCost(Array(FixedCostItem(MethodDesc(SGroupElement.GetEncodedMethod), FixedCost(JitCost(3)))))), + FixedCostItem(MethodDesc(SGroupElement.GetEncodedMethod), FixedCost(JitCost(250))), FixedCostItem(DecodePoint), - FixedCostItem(ValUse) + FixedCostItem(ValUse), + FixedCostItem(NamedDesc("EQ_GroupElement"), FixedCost(JitCost(172))) ) ) - def success[T](v: T) = Expected(Success(v), 38340, cost) + def success[T](v: T) = Expected(Success(v), 38340, costDetails, 1857) Seq( (ge1, success(true)), (ge2, success(true)), @@ -2673,19 +2745,7 @@ class SigmaDslSpecification extends SigmaDslTesting property("GroupElement.negate equivalence") { verifyCases( { - val cost = TracedCost( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(PropertyCall), - MethodCallCostItem(TracedCost(Array(FixedCostItem(MethodDesc(SGroupElement.NegateMethod), FixedCost(JitCost(1)))))) - ) - ) - def success[T](v: T) = Expected(Success(v), 36292, cost) + def success[T](v: T) = Expected(Success(v), 36292, methodCostDetails(SGroupElement.NegateMethod, 45), 1805) Seq( (ge1, success(Helpers.decodeGroupElement("02358d53f01276211f92d0aefbd278805121d4ff6eb534b777af1ee8abae5b2056"))), (ge2, success(Helpers.decodeGroupElement("03dba7b94b111f3894e2f9120b577da595ec7d58d488485adf73bf4e153af63575"))), @@ -2703,22 +2763,16 @@ class SigmaDslSpecification extends SigmaDslTesting } property("GroupElement.exp equivalence") { - val cases = { - val cost = TracedCost( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(ValUse), - FixedCostItem(SelectField), - FixedCostItem(Exponentiate) - ) + val costDetails = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(Exponentiate) ) - def success[T](v: T) = Expected(Success(v), 41484, cost) + ) + val cases = { + def success[T](v: T) = Expected(Success(v), 41484, costDetails, 1893) Seq( ((ge1, CBigInt(new BigInteger("-25c80b560dd7844e2efd10f80f7ee57d", 16))), success(Helpers.decodeGroupElement("023a850181b7b73f92a5bbfa0bfc78f5bbb6ff00645ddde501037017e1a2251e2e"))), @@ -2735,7 +2789,8 @@ class SigmaDslSpecification extends SigmaDslTesting if (lowerMethodCallsInTests) { verifyCases(cases, existingFeature( - scalaFunc, script, + scalaFunc, + script, FuncValue( Vector((1, STuple(Vector(SGroupElement, SBigInt)))), Exponentiate( @@ -2766,10 +2821,19 @@ class SigmaDslSpecification extends SigmaDslTesting Success(Helpers.decodeGroupElement("023a850181b7b73f92a5bbfa0bfc78f5bbb6ff00645ddde501037017e1a2251e2e")), Some(999) ) + val details = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(SGroupElement.ExponentiateMethod, FixedCost(JitCost(900))) + ) + ) Seq( // expected result for each version - 0 -> ( res -> None ), - 1 -> ( res -> None ), - 2 -> ( res -> None ) + 0 -> ( res -> Some(details) ), + 1 -> ( res -> Some(details) ), + 2 -> ( res -> Some(details) ) ) } ) @@ -2808,21 +2872,15 @@ class SigmaDslSpecification extends SigmaDslTesting if (lowerMethodCallsInTests) { verifyCases( { - val cost = TracedCost( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), + val costDetails = TracedCost( + traceBase ++ Array( FixedCostItem(SelectField), FixedCostItem(ValUse), FixedCostItem(SelectField), FixedCostItem(MultiplyGroup) ) ) - def success[T](v: T) = Expected(Success(v), 36457, cost) + def success[T](v: T) = Expected(Success(v), 36457, costDetails, 1807) Seq( ((ge1, Helpers.decodeGroupElement("03e132ca090614bd6c9f811e91f6daae61f16968a1e6c694ed65aacd1b1092320e")), success(Helpers.decodeGroupElement("02bc48937b4a66f249a32dfb4d2efd0743dc88d46d770b8c5d39fd03325ba211df"))), @@ -2864,11 +2922,14 @@ class SigmaDslSpecification extends SigmaDslTesting Success(Helpers.decodeGroupElement("02bc48937b4a66f249a32dfb4d2efd0743dc88d46d770b8c5d39fd03325ba211df")), Some(139) ) - Seq( // expected result for each version - 0 -> ( res -> None ), - 1 -> ( res -> None ), - 2 -> ( res -> None ) - ) + val details = TracedCost(traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(SGroupElement.MultiplyMethod, FixedCost(JitCost(40))) + )) + Seq.tabulate(3)(_ -> ( res -> Some(details) )) // expected result for each version } ) ) @@ -2924,7 +2985,7 @@ class SigmaDslSpecification extends SigmaDslTesting } verifyCases( { - def success[T](v: T) = Expected(Success(v), 36182) + def success[T](v: T) = Expected(Success(v), 36182, methodCostDetails(SAvlTree.digestMethod, 15), 1787) Seq( (t1, success(Helpers.decodeBytes("000183807f66b301530120ff7fc6bd6601ff01ff7f7d2bedbbffff00187fe89094"))), (t2, success(Helpers.decodeBytes("ff000d937f80ffd731ed802d24358001ff8080ff71007f00ad37e0a7ae43fff95b"))), @@ -2937,7 +2998,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36260) + def success[T](v: T) = Expected(Success(v), 36260, methodCostDetails(SAvlTree.enabledOperationsMethod, 15), 1785) Seq( (t1, success(6.toByte)), (t2, success(0.toByte)), @@ -2950,7 +3011,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36136) + def success[T](v: T) = Expected(Success(v), 36136, methodCostDetails(SAvlTree.keyLengthMethod, 15), 1785) Seq( (t1, success(1)), (t2, success(32)), @@ -2963,11 +3024,11 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 37151) + def success[T](v: T, newCost: Int) = Expected(Success(v), 37151, methodCostDetails(SAvlTree.valueLengthOptMethod, 15), newCost) Seq( - (t1, success(Some(1))), - (t2, success(Some(64))), - (t3, success(None)) + (t1, success(Some(1), 1786)), + (t2, success(Some(64), 1786)), + (t3, success(None, 1785)) ) }, existingFeature((t: AvlTree) => t.valueLengthOpt, @@ -2976,7 +3037,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36479) + def success[T](v: T) = Expected(Success(v), 36479, methodCostDetails(SAvlTree.isInsertAllowedMethod, 15), 1785) Seq( (t1, success(false)), (t2, success(false)), @@ -2989,7 +3050,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36096) + def success[T](v: T) = Expected(Success(v), 36096, methodCostDetails(SAvlTree.isUpdateAllowedMethod, 15), 1785) Seq( (t1, success(true)), (t2, success(false)), @@ -3002,7 +3063,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36502) + def success[T](v: T) = Expected(Success(v), 36502, methodCostDetails(SAvlTree.isRemoveAllowedMethod, 15), 1785) Seq( (t1, success(true)), (t2, success(false)), @@ -3202,13 +3263,26 @@ class SigmaDslSpecification extends SigmaDslTesting ) )) - def success[T](v: T) = Expected(Success(v), 0) - - { // getMany with a bunch of existing keys - val (keysArr, valuesArr, _, avlProver) = sampleAvlProver - val keys = Colls.fromArray(keysArr.slice(0, 20)) - val expRes = Colls.fromArray(valuesArr.slice(0, 20).map(Option(_))) - + { + val keysArr = + Array( + Colls.fromArray(Array[Byte](0,14,54,-1,-128,-61,-89,72,27,34,1,-1,62,-48,0,8,74,1,82,-48,-41,100,-66,64,127,45,1,-1,0,-128,-16,-57)), + Colls.fromArray(Array[Byte](127,-128,-1,127,-96,-1,-63,1,25,43,127,-122,127,-43,0,-1,-57,113,-6,1,1,0,15,1,-104,-1,-55,101,115,-94,-128,94)), + Colls.fromArray(Array[Byte](-60,-26,117,124,-92,104,106,-1,-1,-1,-29,121,-98,54,10,-105,127,13,-1,0,-90,0,-125,-13,-1,-79,-87,127,0,127,0,0)), + Colls.fromArray(Array[Byte](84,127,-44,-65,1,-77,39,-128,113,14,1,-128,127,48,-53,60,-5,-19,123,0,-128,127,-28,0,104,-1,0,1,-51,124,-78,67)), + Colls.fromArray(Array[Byte](12,56,-25,-128,1,-128,-128,70,19,37,0,-1,1,87,-20,-128,80,127,-66,-1,83,-1,111,0,-34,0,49,-77,1,0,61,-1)) + ) + val valuesArr = + Array( + Colls.fromArray(Array[Byte](-87,0,-102,88,-128,-54,66,1,-128,-16,0,1,-44,0,35,-32,-23,40,127,-97,49,-1,127,1,-84,115,127,61,-84,-63,-104,-9,-116,-26,9,-93,-128,0,11,127,0,-128,-1,-128,-1,127,-110,-128,0,0,90,-126,28,0,42,-71,-1,37,-26,0,124,-72,68,26,14)), + Colls.fromArray(Array[Byte](84,106,-48,-17,-1,44,127,-128,0,86,-1)), + Colls.fromArray(Array[Byte](127,-128,-60,1,118,-32,-72,-9,101,0,0,-68,-51,8,95,127)), + Colls.fromArray(Array[Byte](127,-88,127,-101,-128,77,-25,-72,-86,127,127,127,-88,0,-128)), + Colls.fromArray(Array[Byte](2,5,-128,127,46,0,1,127,-9,64,-13,0,19,-112,124,1,20,52,65,-31,-112,114,0,18,-1,-88,-128,118,-126,-1,0,112,119,-1,20,84,11,-23,113,-1,71,-77,127,11,1,-128,63,-23,0,127,-55,42,8,127,126,115,59,70,127,102,-109,-128,127,41,-128,127,127,15,1,127,80,-29,0,8,-127,-96,-1,37,106,76,0,-128,-128,-128,-102,52,0,-11,1,-1,71)) + ) + val (_, avlProver) = createAvlTreeAndProver(keysArr.zip(valuesArr):_*) + val keys = Colls.fromArray(keysArr) + val expRes = Colls.fromArray(valuesArr).map(Option(_)) keys.foreach { key => avlProver.performOneOperation(Lookup(ADKey @@ key.toArray)) } @@ -3217,33 +3291,113 @@ class SigmaDslSpecification extends SigmaDslTesting val tree = SigmaDsl.avlTree(AvlTreeFlags.ReadOnly.serializeToByte, digest, 32, None) val input = (tree, (keys, proof)) - getMany.checkExpected(input, success(expRes)) + val costDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + SeqCostItem(NamedDesc("CreateAvlVerifier"), PerItemCost(JitCost(110), JitCost(20), 64), 456), + SeqCostItem(NamedDesc("LookupAvlTree"), PerItemCost(JitCost(40), JitCost(10), 1), 3), + SeqCostItem(NamedDesc("LookupAvlTree"), PerItemCost(JitCost(40), JitCost(10), 1), 3), + SeqCostItem(NamedDesc("LookupAvlTree"), PerItemCost(JitCost(40), JitCost(10), 1), 3), + SeqCostItem(NamedDesc("LookupAvlTree"), PerItemCost(JitCost(40), JitCost(10), 1), 3), + SeqCostItem(NamedDesc("LookupAvlTree"), PerItemCost(JitCost(40), JitCost(10), 1), 3) + ) + ) + + getMany.checkExpected(input, Expected(Success(expRes), 38991, costDetails, 1865)) } - val (keysArr, valuesArr, _, avlProver) = sampleAvlProver - val key = keysArr(0) - val value = valuesArr(0) + val key = Colls.fromArray(Array[Byte](-16,-128,99,86,1,-128,-36,-83,109,72,-124,-114,1,-32,15,127,-30,125,127,1,-102,-53,-53,-128,-107,0,64,8,1,127,22,1)) + val value = Colls.fromArray(Array[Byte](0,41,-78,1,113,-128,0,-128,1,-92,0,1,1,34,127,-1,56,-1,-60,89,1,-20,-92)) + val (tree, avlProver) = createAvlTreeAndProver(key -> value) val otherKey = key.map(x => (-x).toByte) // any other different from key - val table = Table(("key", "contains", "valueOpt"), - (key, true, Some(value)), - (otherKey, false, None) + // Final cost is baseCost + additionalCost, baseCost is specified in test scenario below + val table = Table(("key", "contains", "valueOpt", "additionalCost", "additionalCostDetails"), + (key, true, Some(value), 2, 23), + (otherKey, false, None, 0, 0) ) - forAll(table) { (key, okContains, valueOpt) => + forAll(table) { (key, okContains, valueOpt, additionalCost, additionalDetails) => avlProver.performOneOperation(Lookup(ADKey @@ key.toArray)) val proof = avlProver.generateProof().toColl val digest = avlProver.digest.toColl val tree = SigmaDsl.avlTree(AvlTreeFlags.ReadOnly.serializeToByte, digest, 32, None) + def costDetails(i: Int) = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + SeqCostItem(NamedDesc("CreateAvlVerifier"), PerItemCost(JitCost(110), JitCost(20), 64), i), + SeqCostItem(NamedDesc("LookupAvlTree"), PerItemCost(JitCost(40), JitCost(10), 1), 1) + ) + ) + + val updateDigestCostDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(SAvlTree.updateDigestMethod, FixedCost(JitCost(40))) + ) + ) + + val updateOperationsCostDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(SAvlTree.updateOperationsMethod, FixedCost(JitCost(45))) + ) + ) + // positive test { val input = (tree, (key, proof)) - contains.checkExpected(input, success(okContains)) - get.checkExpected(input, success(valueOpt)) - - contains.checkVerify(input, Expected(value = Success(okContains), cost = 37850)) - get.checkVerify(input, Expected(value = Success(valueOpt), cost = 38372)) + contains.checkExpected(input, Expected(Success(okContains), 37850, costDetails(105 + additionalDetails), 1810)) + get.checkExpected(input, Expected(Success(valueOpt), 38372, costDetails(105 + additionalDetails), 1810 + additionalCost)) } val keys = Colls.fromItems(key) @@ -3251,15 +3405,14 @@ class SigmaDslSpecification extends SigmaDslTesting { val input = (tree, (keys, proof)) - getMany.checkExpected(input, success(expRes)) - getMany.checkVerify(input, Expected(value = Success(expRes), cost = 38991)) + getMany.checkExpected(input, Expected(Success(expRes), 38991, costDetails(105 + additionalDetails), 1811 + additionalCost)) } { val input = (tree, digest) val (res, _) = updateDigest.checkEquality(input).getOrThrow res.digest shouldBe digest - updateDigest.checkVerify(input, Expected(value = Success(res), cost = 36341)) + updateDigest.checkExpected(input, Expected(Success(res), 36341, updateDigestCostDetails, 1791)) } val newOps = 1.toByte @@ -3268,7 +3421,7 @@ class SigmaDslSpecification extends SigmaDslTesting val input = (tree, newOps) val (res,_) = updateOperations.checkEquality(input).getOrThrow res.enabledOperations shouldBe newOps - updateOperations.checkVerify(input, Expected(value = Success(res), cost = 36341)) + updateOperations.checkExpected(input, Expected(Success(res), 36341, updateOperationsCostDetails, 1791)) } // negative tests: invalid proof @@ -3278,7 +3431,7 @@ class SigmaDslSpecification extends SigmaDslTesting val input = (tree, (key, invalidProof)) val (res, _) = contains.checkEquality(input).getOrThrow res shouldBe false - contains.checkVerify(input, Expected(value = Success(res), cost = 37850)) + contains.checkExpected(input, Expected(Success(res), 37850, costDetails(105 + additionalDetails), 1810)) } { @@ -3392,6 +3545,34 @@ class SigmaDslSpecification extends SigmaDslTesting ) )) + val testTraceBase = Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(SAvlTree.isInsertAllowedMethod, FixedCost(JitCost(15))) + ) + val costDetails1 = TracedCost(testTraceBase) + val costDetails2 = TracedCost( + testTraceBase ++ Array( + SeqCostItem(NamedDesc("CreateAvlVerifier"), PerItemCost(JitCost(110), JitCost(20), 64), 70), + SeqCostItem(NamedDesc("InsertIntoAvlTree"), PerItemCost(JitCost(40), JitCost(10), 1), 1), + FixedCostItem(SAvlTree.updateDigestMethod, FixedCost(JitCost(40))) + ) + ) + forAll(keyCollGen, bytesCollGen) { (key, value) => val (tree, avlProver) = createAvlTreeAndProver() val preInsertDigest = avlProver.digest.toColl @@ -3403,7 +3584,7 @@ class SigmaDslSpecification extends SigmaDslTesting val input = (preInsertTree, (kvs, insertProof)) val (res, _) = insert.checkEquality(input).getOrThrow res.isDefined shouldBe true - insert.checkVerify(input, Expected(value = Success(res), cost = 38501)) + insert.checkExpected(input, Expected(Success(res), 38501, costDetails2, 1816)) } { // negative: readonly tree @@ -3411,7 +3592,7 @@ class SigmaDslSpecification extends SigmaDslTesting val input = (readonlyTree, (kvs, insertProof)) val (res, _) = insert.checkEquality(input).getOrThrow res.isDefined shouldBe false - insert.checkVerify(input, Expected(value = Success(res), cost = 38501)) + insert.checkExpected(input, Expected(Success(res), 38501, costDetails1, 1792)) } { // negative: invalid key @@ -3421,7 +3602,7 @@ class SigmaDslSpecification extends SigmaDslTesting val input = (tree, (invalidKvs, insertProof)) val (res, _) = insert.checkEquality(input).getOrThrow res.isDefined shouldBe true // TODO v6.0: should it really be true? (looks like a bug) - insert.checkVerify(input, Expected(value = Success(res), cost = 38501)) + insert.checkExpected(input, Expected(Success(res), 38501, costDetails2, 1816)) } { // negative: invalid proof @@ -3503,67 +3684,95 @@ class SigmaDslSpecification extends SigmaDslTesting )) val cost = 40952 - def success[T](v: T) = Expected(Success(v), 0) - - forAll(keyCollGen, bytesCollGen) { (key, value) => - val (_, avlProver) = createAvlTreeAndProver(key -> value) - val preUpdateDigest = avlProver.digest.toColl - val newValue = bytesCollGen.sample.get - val updateProof = performUpdate(avlProver, key, newValue) - val kvs = Colls.fromItems((key -> newValue)) - val endDigest = avlProver.digest.toColl + val testTraceBase = Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(SAvlTree.isUpdateAllowedMethod, FixedCost(JitCost(15))) + ) + val costDetails1 = TracedCost(testTraceBase) + val costDetails2 = TracedCost( + testTraceBase ++ Array( + SeqCostItem(NamedDesc("CreateAvlVerifier"), PerItemCost(JitCost(110), JitCost(20), 64), 111), + SeqCostItem(NamedDesc("UpdateAvlTree"), PerItemCost(JitCost(120), JitCost(20), 1), 1), + FixedCostItem(SAvlTree.updateDigestMethod, FixedCost(JitCost(40))) + ) + ) + val costDetails3 = TracedCost( + testTraceBase ++ Array( + SeqCostItem(NamedDesc("CreateAvlVerifier"), PerItemCost(JitCost(110), JitCost(20), 64), 111), + SeqCostItem(NamedDesc("UpdateAvlTree"), PerItemCost(JitCost(120), JitCost(20), 1), 1) + ) + ) - { // positive: update to newValue - val preUpdateTree = createTree(preUpdateDigest, updateAllowed = true) - val endTree = preUpdateTree.updateDigest(endDigest) - val input = (preUpdateTree, (kvs, updateProof)) - val res = Some(endTree) - update.checkExpected(input, success(res)) - update.checkVerify(input, Expected(value = Success(res), cost = cost)) - } + val key = Colls.fromArray(Array[Byte](1,0,1,1,73,-67,-128,1,1,0,93,0,127,87,95,51,1,127,1,-3,74,-66,-128,1,89,-18,1,-1,-62,0,-33,51)) + val value = Colls.fromArray(Array[Byte](1,-50,1,-128,120,1)) + val (_, avlProver) = createAvlTreeAndProver(key -> value) + val preUpdateDigest = avlProver.digest.toColl + // val newValue = bytesCollGen.sample.get + val newValue = Colls.fromArray(Array[Byte](2,-1,127,91,0,-1,-128,-1,38,-128,-105,-68,-128,-128,127,127,127,-74,88,127,127,127,-81,-30,-89,121,127,-1,-1,-34,127,1,-12,-128,108,75,127,-14,-63,-128,-103,127,1,-57,0,1,-128,127,-85,23,0,-128,70,-110,127,-85,-30,15,-1,-71,0,127,1,42,127,-118,-1,0,-53,126,42,0,127,127,0,-10,-1,127,19,-4,-1,-88,-128,-96,61,-116,127,-111,6,-128,-1,-86,-39,114,0,127,-92,40)) + val updateProof = performUpdate(avlProver, key, newValue) + val kvs = Colls.fromItems((key -> newValue)) + val endDigest = avlProver.digest.toColl + + { // positive: update to newValue + val preUpdateTree = createTree(preUpdateDigest, updateAllowed = true) + val endTree = preUpdateTree.updateDigest(endDigest) + val input = (preUpdateTree, (kvs, updateProof)) + val res = Some(endTree) + update.checkExpected(input, Expected(Success(res), cost, costDetails2, 1825)) + } - { // positive: update to the same value (identity operation) - val tree = createTree(preUpdateDigest, updateAllowed = true) - val keys = Colls.fromItems((key -> value)) - val input = (tree, (keys, updateProof)) - val res = Some(tree) - update.checkExpected(input, success(res)) - update.checkVerify(input, Expected(value = Success(res), cost = cost)) - } + { // positive: update to the same value (identity operation) + val tree = createTree(preUpdateDigest, updateAllowed = true) + val keys = Colls.fromItems((key -> value)) + val input = (tree, (keys, updateProof)) + val res = Some(tree) + update.checkExpected(input, Expected(Success(res), cost, costDetails2, 1825)) + } - { // negative: readonly tree - val readonlyTree = createTree(preUpdateDigest) - val input = (readonlyTree, (kvs, updateProof)) - update.checkExpected(input, success(None)) - update.checkVerify(input, Expected(value = Success(None), cost = cost)) - } + { // negative: readonly tree + val readonlyTree = createTree(preUpdateDigest) + val input = (readonlyTree, (kvs, updateProof)) + update.checkExpected(input, Expected(Success(None), cost, costDetails1, 1792)) + } - { // negative: invalid key - val tree = createTree(preUpdateDigest, updateAllowed = true) - val invalidKey = key.map(x => (-x).toByte) // any other different from key - val invalidKvs = Colls.fromItems((invalidKey -> newValue)) - val input = (tree, (invalidKvs, updateProof)) - update.checkExpected(input, success(None)) - update.checkVerify(input, Expected(value = Success(None), cost = cost)) - } + { // negative: invalid key + val tree = createTree(preUpdateDigest, updateAllowed = true) + val invalidKey = key.map(x => (-x).toByte) // any other different from key + val invalidKvs = Colls.fromItems((invalidKey -> newValue)) + val input = (tree, (invalidKvs, updateProof)) + update.checkExpected(input, Expected(Success(None), cost, costDetails3, 1821)) + } - { // negative: invalid value (different from the value in the proof) - val tree = createTree(preUpdateDigest, updateAllowed = true) - val invalidValue = newValue.map(x => (-x).toByte) - val invalidKvs = Colls.fromItems((key -> invalidValue)) - val input = (tree, (invalidKvs, updateProof)) - val (res, _) = update.checkEquality(input).getOrThrow - res.isDefined shouldBe true // TODO v6.0: should it really be true? (looks like a bug) - update.checkVerify(input, Expected(value = Success(res), cost = cost)) - } + { // negative: invalid value (different from the value in the proof) + val tree = createTree(preUpdateDigest, updateAllowed = true) + val invalidValue = newValue.map(x => (-x).toByte) + val invalidKvs = Colls.fromItems((key -> invalidValue)) + val input = (tree, (invalidKvs, updateProof)) + val (res, _) = update.checkEquality(input).getOrThrow + res.isDefined shouldBe true // TODO v6.0: should it really be true? (looks like a bug) + update.checkExpected(input, Expected(Success(res), cost, costDetails2, 1825)) + } - { // negative: invalid proof - val tree = createTree(preUpdateDigest, updateAllowed = true) - val invalidProof = updateProof.map(x => (-x).toByte) // any other different from proof - val input = (tree, (kvs, invalidProof)) - update.checkExpected(input, success(None)) - update.checkVerify(input, Expected(value = Success(None), cost = cost)) - } + { // negative: invalid proof + val tree = createTree(preUpdateDigest, updateAllowed = true) + val invalidProof = updateProof.map(x => (-x).toByte) // any other different from proof + val input = (tree, (kvs, invalidProof)) + update.checkExpected(input, Expected(Success(None), cost, costDetails3, 1821)) } } @@ -3604,13 +3813,68 @@ class SigmaDslSpecification extends SigmaDslTesting ) )) - def success[T](v: T) = Expected(Success(v), 0) + val testTraceBase = Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(SAvlTree.isRemoveAllowedMethod, FixedCost(JitCost(15))) + ) + val costDetails1 = TracedCost( + testTraceBase ++ Array( + SeqCostItem(NamedDesc("CreateAvlVerifier"), PerItemCost(JitCost(110), JitCost(20), 64), 436), + SeqCostItem(NamedDesc("RemoveAvlTree"), PerItemCost(JitCost(100), JitCost(15), 1), 3), + SeqCostItem(NamedDesc("RemoveAvlTree"), PerItemCost(JitCost(100), JitCost(15), 1), 3), + FixedCostItem(SAvlTree.digestMethod, FixedCost(JitCost(15))), + FixedCostItem(SAvlTree.updateDigestMethod, FixedCost(JitCost(40))) + ) + ) + val costDetails2 = TracedCost( + testTraceBase ++ Array( + SeqCostItem(NamedDesc("CreateAvlVerifier"), PerItemCost(JitCost(110), JitCost(20), 64), 140), + SeqCostItem(NamedDesc("RemoveAvlTree"), PerItemCost(JitCost(100), JitCost(15), 1), 1), + FixedCostItem(SAvlTree.digestMethod, FixedCost(JitCost(15))), + FixedCostItem(SAvlTree.updateDigestMethod, FixedCost(JitCost(40))) + ) + ) + val costDetails3 = TracedCost(testTraceBase) + val costDetails4 = TracedCost( + testTraceBase ++ Array( + SeqCostItem(NamedDesc("CreateAvlVerifier"), PerItemCost(JitCost(110), JitCost(20), 64), 140), + SeqCostItem(NamedDesc("RemoveAvlTree"), PerItemCost(JitCost(100), JitCost(15), 1), 1), + FixedCostItem(SAvlTree.digestMethod, FixedCost(JitCost(15))) + ) + ) - { // positive test with many keys in the tree and to remove - val keys = arrayOfN(100, keyCollGen).sample.get - val values = arrayOfN(100, bytesCollGen).sample.get - val (_, avlProver) = createAvlTreeAndProver(keys.zip(values):_*) - val preRemoveDigest = avlProver.digest.toColl + { + val keys = Array( + Colls.fromArray(Array[Byte](6,71,1,-123,-1,17,-1,-1,-128,-1,-99,127,2,-37,-1,-17,-1,-90,-33,-50,-122,127,1,127,-81,1,-57,118,-38,-36,-2,1)), + Colls.fromArray(Array[Byte](-84,-128,1,0,30,0,73,127,71,1,0,39,127,-1,-109,66,0,1,-128,-43,-1,-95,-55,-97,12,1,-1,0,-128,-1,5,0)), + Colls.fromArray(Array[Byte](0,-84,1,-1,-128,93,-21,0,-128,0,-128,-128,85,-128,-123,-1,-70,0,38,-1,123,-1,1,21,0,-11,-59,122,-108,-64,1,124)), + Colls.fromArray(Array[Byte](1,-29,-1,0,-1,0,0,0,1,44,0,2,0,17,1,-36,50,58,118,-125,108,-93,3,65,-128,77,127,109,-121,-61,-128,-128)), + Colls.fromArray(Array[Byte](127,0,0,70,127,1,-109,60,-128,-106,-77,-1,-1,0,127,-108,-128,0,0,-27,-9,-128,89,127,107,68,-76,3,-102,127,4,0)) + ) + val values = Array( + Colls.fromArray(Array[Byte](-1,91,0,31,-86,-1,39,127,76,78,-1,0,0,-112,36,-16,55,-9,-21,45,0,-128,23,-1,1,-128,63,-33,-60,117,116,-53,-19,-1,0,1,-128,0,127,127,16,127,-84,-128,0,1,-5,1,-128,-103,114,-128,-105,-128,79,62,-1,46,0,-128,-40,-1,89,40,103,1,44,-128,97,-107,111,-1,0,-8,1,42,-38,88,127,127,118,127,127,127,-6,-1,20,32,-128,-1,69,1,127,1,127,22,-128,127)), + Colls.fromArray(Array[Byte](-75,-38,-1,0,-127,-104,-128,-128,-47,113,98,-128,-120,101,1,-128,1,-128,19,1,0,10,88,90,-1,-49,-13,127,26,82,-1,-1,-1,1,-1,-62,-128,-128)), + Colls.fromArray(Array[Byte](-95,-76,-128,-128,127,16,0,-1,-18,1,-93,1,127,-128,1,-92,111,-128,59,-1,-128,-1,96,-87,127,101,14,73,-9,-128,-1,1,-128,-1,127,-72,6,127,1,67,-1,-128,3,111,1,1,127,-118,127,43,-99,1,-128,0,127,-128,1,-128,-128,100,1,73,0,127,1,-121,1,104,-50,0,0,-1,119,127,80,-69,-128,23,-128,1,-1,127,18,-128,124,-128)), + Colls.fromArray(Array[Byte](-65,-128,127,0,-7,35,-128,-127,-120,-128,-8,64,-128,16)), + Colls.fromArray(Array[Byte](127,100,8,-128,1,56,113,-35,-50,53,-128,-61,-1)) + ) + val (_, avlProver) = createAvlTreeAndProver(keys.zip(values):_*) + val preRemoveDigest = avlProver.digest.toColl val keysToRemove = keys.zipWithIndex.collect { case (k, i) if i % 2 != 0 => k } val removeProof = performRemove(avlProver, keysToRemove) val endDigest = avlProver.digest.toColl @@ -3619,10 +3883,12 @@ class SigmaDslSpecification extends SigmaDslTesting val endTree = preRemoveTree.updateDigest(endDigest) val input = (preRemoveTree, (Colls.fromArray(keysToRemove), removeProof)) val res = Some(endTree) - remove.checkExpected(input, success(res)) + remove.checkExpected(input, Expected(Success(res), 38270, costDetails1, 1852)) } - forAll(keyCollGen, bytesCollGen) { (key, value) => + { + val key = Colls.fromArray(Array[Byte](-60,42,60,-1,-128,-122,107,-1,-1,-128,47,24,-1,-13,-40,-58,-1,127,-41,-12,100,0,15,-108,-41,127,-7,-1,126,-1,-1,115)) + val value = Colls.fromArray(Array[Byte](0,-40,1,1,-60,-119,-68,0,-128,-128,127,-3,5,54,-1,49,47,33,126,-82,-115,1,0,-123,1,15,-1,-49,-107,73,-1)) val (_, avlProver) = createAvlTreeAndProver(key -> value) val preRemoveDigest = avlProver.digest.toColl val removeProof = performRemove(avlProver, Array(key)) @@ -3635,15 +3901,13 @@ class SigmaDslSpecification extends SigmaDslTesting val endTree = preRemoveTree.updateDigest(endDigest) val input = (preRemoveTree, (keys, removeProof)) val res = Some(endTree) - remove.checkExpected(input, success(res)) - remove.checkVerify(input, Expected(value = Success(res), cost = cost)) + remove.checkExpected(input, Expected(Success(res), cost, costDetails2, 1826)) } { // negative: readonly tree val readonlyTree = createTree(preRemoveDigest) val input = (readonlyTree, (keys, removeProof)) - remove.checkExpected(input, success(None)) - remove.checkVerify(input, Expected(value = Success(None), cost = cost)) + remove.checkExpected(input, Expected(Success(None), cost, costDetails3, 1792)) } { // negative: invalid key @@ -3651,24 +3915,23 @@ class SigmaDslSpecification extends SigmaDslTesting val invalidKey = key.map(x => (-x).toByte) // any other different from `key` val invalidKeys = Colls.fromItems(invalidKey) val input = (tree, (invalidKeys, removeProof)) - remove.checkExpected(input, success(None)) - remove.checkVerify(input, Expected(value = Success(None), cost = cost)) + remove.checkExpected(input, Expected(Success(None), cost, costDetails4, 1822)) } { // negative: invalid proof val tree = createTree(preRemoveDigest, removeAllowed = true) val invalidProof = removeProof.map(x => (-x).toByte) // any other different from `removeProof` val input = (tree, (keys, invalidProof)) - remove.checkExpected(input, success(None)) - remove.checkVerify(input, Expected(value = Success(None), cost = cost)) + remove.checkExpected(input, Expected(Success(None), cost, costDetails4, 1822)) } } } property("longToByteArray equivalence") { + val costDetails = CostDetails(traceBase :+ FixedCostItem(CompanionDesc(LongToByteArray), FixedCost(JitCost(17)))) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36007) + def success[T](v: T) = Expected(Success(v), 36007, costDetails, 1787) Seq( (-9223372036854775808L, success(Helpers.decodeBytes("8000000000000000"))), (-1148502660425090565L, success(Helpers.decodeBytes("f00fb2ea55c579fb"))), @@ -3685,9 +3948,10 @@ class SigmaDslSpecification extends SigmaDslTesting } property("byteArrayToBigInt equivalence") { + val costDetails = CostDetails(traceBase :+ FixedCostItem(CompanionDesc(ByteArrayToBigInt), FixedCost(JitCost(30)))) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36536) + def success[T](v: T) = Expected(Success(v), 36536, costDetails, 1787) Seq( (Helpers.decodeBytes(""), Expected(new NumberFormatException("Zero length BigInteger"))), @@ -3698,9 +3962,9 @@ class SigmaDslSpecification extends SigmaDslTesting (Helpers.decodeBytes("ff"), success(CBigInt(new BigInteger("-1", 16)))), (Helpers.decodeBytes("80d6c201"), - Expected(Success(CBigInt(new BigInteger("-7f293dff", 16))), 36539)), + Expected(Success(CBigInt(new BigInteger("-7f293dff", 16))), 36539, costDetails, 1787)), (Helpers.decodeBytes("70d6c20170d6c201"), - Expected(Success(CBigInt(new BigInteger("70d6c20170d6c201", 16))), 36543)), + Expected(Success(CBigInt(new BigInteger("70d6c20170d6c201", 16))), 36543, costDetails, 1787)), (Helpers.decodeBytes( "80e0ff7f02807fff72807f0a00ff7fb7c57f75c11ba2802970fd250052807fc37f6480ffff007fff18eeba44" ), Expected(new ArithmeticException("BigInteger out of 256 bit range"))) @@ -3712,9 +3976,10 @@ class SigmaDslSpecification extends SigmaDslTesting } property("byteArrayToLong equivalence") { + val costDetails = CostDetails(traceBase :+ FixedCostItem(CompanionDesc(ByteArrayToLong), FixedCost(JitCost(16)))) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36092) + def success[T](v: T) = Expected(Success(v), 36092, costDetails, 1785) Seq( (Helpers.decodeBytes(""), Expected(new IllegalArgumentException("array too small: 0 < 8"))), (Helpers.decodeBytes("81"), Expected(new IllegalArgumentException("array too small: 1 < 8"))), @@ -3744,8 +4009,9 @@ class SigmaDslSpecification extends SigmaDslTesting property("Box properties equivalence") { verifyCases( { - def success[T](v: T) = Expected(Success(v), 35984) - Seq( + val costDetails = CostDetails(traceBase :+ FixedCostItem(CompanionDesc(ExtractId), FixedCost(JitCost(12)))) + def success[T](v: T) = Expected(Success(v), 35984, costDetails, 1786) + Seq( (b1, success(Helpers.decodeBytes("5ee78f30ae4e770e44900a46854e9fecb6b12e8112556ef1cd19aef633b4421e"))), (b2, success(Helpers.decodeBytes("3a0089be265460e29ca47d26e5b55a6f3e3ffaf5b4aed941410a2437913848ad"))) ) @@ -3756,7 +4022,8 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35882) + val costDetails = CostDetails(traceBase :+ FixedCostItem(CompanionDesc(ExtractAmount), FixedCost(JitCost(8)))) + def success[T](v: T) = Expected(Success(v), 35882, costDetails, 1784) Seq( (b1, success(9223372036854775807L)), (b2, success(12345L)) @@ -3768,7 +4035,8 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35938) + val costDetails = CostDetails(traceBase :+ FixedCostItem(CompanionDesc(ExtractScriptBytes), FixedCost(JitCost(10)))) + def success[T](v: T) = Expected(Success(v), 35938, costDetails, 1786) Seq( (b1, success(Helpers.decodeBytes( "100108cd0297c44a12f4eb99a85d298fa3ba829b5b42b9f63798c980ece801cc663cc5fc9e7300" @@ -3782,7 +4050,8 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36012) + val costDetails = CostDetails(traceBase :+ FixedCostItem(CompanionDesc(ExtractBytes), FixedCost(JitCost(12)))) + def success[T](v: T) = Expected(Success(v), 36012, costDetails, 1786) Seq( (b1, success(Helpers.decodeBytes( "ffffffffffffffff7f100108cd0297c44a12f4eb99a85d298fa3ba829b5b42b9f63798c980ece801cc663cc5fc9e73009fac29026e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f000180ade204a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600f4030201000e067fc87f7f01ff218301ae8000018008637f0021fb9e00018055486f0b514121016a00ff718080bcb001" @@ -3798,7 +4067,8 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35954) + val costDetails = CostDetails(traceBase :+ FixedCostItem(CompanionDesc(ExtractBytesWithNoRef), FixedCost(JitCost(12)))) + def success[T](v: T) = Expected(Success(v), 35954, costDetails, 1786) Seq( (b1, success(Helpers.decodeBytes( "ffffffffffffffff7f100108cd0297c44a12f4eb99a85d298fa3ba829b5b42b9f63798c980ece801cc663cc5fc9e73009fac29026e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f000180ade204a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600f4030201000e067fc87f7f01ff" @@ -3814,7 +4084,8 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36074) + val costDetails = CostDetails(traceBase :+ FixedCostItem(CompanionDesc(ExtractCreationInfo), FixedCost(JitCost(16)))) + def success[T](v: T) = Expected(Success(v), 36074, costDetails, 1787) Seq( (b1, success(( 677407, @@ -3837,8 +4108,8 @@ class SigmaDslSpecification extends SigmaDslTesting b1 -> Expected(Success(Coll[(Coll[Byte], Long)]( (Helpers.decodeBytes("6e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f0001"), 10000000L), (Helpers.decodeBytes("a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600"), 500L) - ).map(identity)), 36167), - b2 -> Expected(Success(Coll[(Coll[Byte], Long)]().map(identity)), 36157) + ).map(identity)), 36167, methodCostDetails(SBox.tokensMethod, 15), 1792), + b2 -> Expected(Success(Coll[(Coll[Byte], Long)]().map(identity)), 36157, methodCostDetails(SBox.tokensMethod, 15), 1786) ), existingFeature({ (x: Box) => x.tokens }, "{ (x: Box) => x.tokens }", @@ -3879,14 +4150,49 @@ class SigmaDslSpecification extends SigmaDslTesting ErgoBox.R4 -> ByteConstant(2.toByte) )) val box4 = boxWithRegisters(Map.empty) + val expCostDetails1 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(ExtractRegisterAs), FixedCost(JitCost(50))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(OptionIsDefined), FixedCost(JitCost(10))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + FixedCostItem(ValUse), + FixedCostItem(OptionGet) + ) + ) + val expCostDetails2 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(ExtractRegisterAs), FixedCost(JitCost(50))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(OptionIsDefined), FixedCost(JitCost(10))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + FixedCostItem(Constant) + ) + ) verifyCases( Seq( - (box1, Expected(Success(1024.toShort), cost = 37190)), + (box1, Expected(Success(1024.toShort), 37190, expCostDetails1, 1794)), (box2, Expected( new InvalidType("Cannot getReg[Short](5): invalid type of value TestValue(1048576) at id=5") )), - (box3, Expected(Success(0.toShort), cost = 37190)) + (box3, Expected(Success(0.toShort), 37190, expCostDetails2, 1792)) ), existingFeature( { (x: Box) => @@ -3917,12 +4223,104 @@ class SigmaDslSpecification extends SigmaDslTesting ) ))) + val expCostDetails3 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(ExtractRegisterAs), FixedCost(JitCost(50))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(OptionIsDefined), FixedCost(JitCost(10))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(ExtractRegisterAs), FixedCost(JitCost(50))), + FixedCostItem(OptionGet), + TypeBasedCostItem(Upcast, SInt) + ) + ) + + val expCostDetails4 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(ExtractRegisterAs), FixedCost(JitCost(50))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(OptionIsDefined), FixedCost(JitCost(10))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(ExtractRegisterAs), FixedCost(JitCost(50))), + FixedCostItem(OptionGet) + ) + ) + + val expCostDetails5 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(ExtractRegisterAs), FixedCost(JitCost(50))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(CompanionDesc(OptionIsDefined), FixedCost(JitCost(10))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(CompanionDesc(If), FixedCost(JitCost(10))), + FixedCostItem(Constant) + ) + ) + + verifyCases( Seq( - (box1, Expected(Success(1024), cost = 39782)), - (box2, Expected(Success(1024 * 1024), cost = 39782)), - (box3, Expected(Success(0), cost = 39782)), - (box4, Expected(Success(-1), cost = 39782)) + (box1, Expected(Success(1024), cost = 39782, expCostDetails3, 1805)), + (box2, Expected(Success(1024 * 1024), cost = 39782, expCostDetails4, 1806)), + (box3, Expected(Success(0), cost = 39782, expCostDetails5, 1799)), + (box4, Expected(Success(-1), cost = 39782, expCostDetails2, 1792)) ), existingFeature( { (x: Box) => @@ -4008,9 +4406,15 @@ class SigmaDslSpecification extends SigmaDslTesting // ErgoBox.R6 -> Constant[SOption[SInt.type]](Option(10), SOption(SInt)), ))) + val expCostDetails = TracedCost( + traceBase ++ Array( + FixedCostItem(CompanionDesc(ExtractRegisterAs), FixedCost(JitCost(50))), + FixedCostItem(OptionGet) + ) + ) verifyCases( Seq( - (box1, Expected(Success(1.toByte), cost = 36253)), + (box1, Expected(Success(1.toByte), cost = 36253, expCostDetails, 1790)), (box2, Expected(new InvalidType("Cannot getReg[Byte](4): invalid type of value Value(Coll(1)) at id=4"))) ), existingFeature((x: Box) => x.R4[Byte].get, @@ -4022,7 +4426,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - (box1, Expected(Success(1024.toShort), cost = 36253)), + (box1, Expected(Success(1024.toShort), cost = 36253, expCostDetails, 1790)), (box2, Expected(new NoSuchElementException("None.get"))) ), existingFeature((x: Box) => x.R5[Short].get, @@ -4034,7 +4438,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - (box1, Expected(Success(1024 * 1024), cost = 36253)) + (box1, Expected(Success(1024 * 1024), cost = 36253, expCostDetails, 1790)) ), existingFeature((x: Box) => x.R6[Int].get, "{ (x: Box) => x.R6[Int].get }", @@ -4045,7 +4449,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - (box1, Expected(Success(1024.toLong), cost = 36253)) + (box1, Expected(Success(1024.toLong), cost = 36253, expCostDetails, 1790)) ), existingFeature((x: Box) => x.R7[Long].get, "{ (x: Box) => x.R7[Long].get }", @@ -4056,7 +4460,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - (box1, Expected(Success(CBigInt(BigInteger.valueOf(222L))), cost = 36253)) + (box1, Expected(Success(CBigInt(BigInteger.valueOf(222L))), cost = 36253, expCostDetails, 1790)) ), existingFeature((x: Box) => x.R8[BigInt].get, "{ (x: Box) => x.R8[BigInt].get }", @@ -4076,7 +4480,10 @@ class SigmaDslSpecification extends SigmaDslTesting 32, None ) - )), cost = 36253) + )), + cost = 36253, + expCostDetails, + 1790) )), existingFeature((x: Box) => x.R9[AvlTree].get, "{ (x: Box) => x.R9[AvlTree].get }", @@ -4087,7 +4494,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - (box3, Expected(Success(10), cost = 36468)) + (box3, Expected(Success(10), cost = 36468))//, expCostDetails, 1790)) ), existingFeature((x: Box) => x.R4[(Int, Long)].get._1, "{ (x: Box) => x.R4[(Int, Long)].get._1 }", @@ -4101,7 +4508,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - (box3, Expected(Success(10), cost = 36468)) + (box3, Expected(Success(10), cost = 36468))//, expCostDetails, 1790)) ), existingFeature((x: Box) => x.R5[(Int, Option[Long])].get._1, "{ (x: Box) => x.R5[(Int, Option[Long])].get._1 }", @@ -4145,36 +4552,38 @@ class SigmaDslSpecification extends SigmaDslTesting } property("PreHeader properties equivalence") { + + verifyCases( - Seq((preH1, Expected(Success(0.toByte), cost = 37022))), + Seq((preH1, Expected(Success(0.toByte), cost = 37022, methodCostDetails(SPreHeader.versionMethod, 10), 1785))), existingPropTest("version", { (x: PreHeader) => x.version })) verifyCases( Seq((preH1, Expected(Success( Helpers.decodeBytes("7fff7fdd6f62018bae0001006d9ca888ff7f56ff8006573700a167f17f2c9f40")), - cost = 36121))), + cost = 36121, methodCostDetails(SPreHeader.parentIdMethod, 10), 1786))), existingPropTest("parentId", { (x: PreHeader) => x.parentId })) verifyCases( - Seq((preH1, Expected(Success(6306290372572472443L), cost = 36147))), + Seq((preH1, Expected(Success(6306290372572472443L), cost = 36147, methodCostDetails(SPreHeader.timestampMethod, 10), 1785))), existingPropTest("timestamp", { (x: PreHeader) => x.timestamp })) verifyCases( - Seq((preH1, Expected(Success(-3683306095029417063L), cost = 36127))), + Seq((preH1, Expected(Success(-3683306095029417063L), cost = 36127, methodCostDetails(SPreHeader.nBitsMethod, 10), 1785))), existingPropTest("nBits", { (x: PreHeader) => x.nBits })) verifyCases( - Seq((preH1, Expected(Success(1), cost = 36136))), + Seq((preH1, Expected(Success(1), cost = 36136, methodCostDetails(SPreHeader.heightMethod, 10), 1785))), existingPropTest("height", { (x: PreHeader) => x.height })) verifyCases( Seq((preH1, Expected(Success( Helpers.decodeGroupElement("026930cb9972e01534918a6f6d6b8e35bc398f57140d13eb3623ea31fbd069939b")), - cost = 36255))), + cost = 36255, methodCostDetails(SPreHeader.minerPkMethod, 10), 1802))), existingPropTest("minerPk", { (x: PreHeader) => x.minerPk })) verifyCases( - Seq((preH1, Expected(Success(Helpers.decodeBytes("ff8087")), cost = 36249))), + Seq((preH1, Expected(Success(Helpers.decodeBytes("ff8087")), cost = 36249, methodCostDetails(SPreHeader.votesMethod,10), 1786))), existingPropTest("votes", { (x: PreHeader) => x.votes })) } @@ -4182,81 +4591,81 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq((h1, Expected(Success( Helpers.decodeBytes("957f008001808080ffe4ffffc8f3802401df40006aa05e017fa8d3f6004c804a")), - cost = 36955))), + cost = 36955, methodCostDetails(SHeader.idMethod, 10), 1786))), existingPropTest("id", { (x: Header) => x.id })) verifyCases( - Seq((h1, Expected(Success(0.toByte), cost = 36124))), + Seq((h1, Expected(Success(0.toByte), cost = 36124, methodCostDetails(SHeader.versionMethod, 10), 1785))), existingPropTest("version", { (x: Header) => x.version })) verifyCases( Seq((h1, Expected(Success( Helpers.decodeBytes("0180dd805b0000ff5400b997fd7f0b9b00de00fb03c47e37806a8186b94f07ff")), - cost = 36097))), + cost = 36097, methodCostDetails(SHeader.parentIdMethod, 10), 1786))), existingPropTest("parentId", { (x: Header) => x.parentId })) verifyCases( Seq((h1, Expected(Success( Helpers.decodeBytes("01f07f60d100ffb970c3007f60ff7f24d4070bb8fffa7fca7f34c10001ffe39d")), - cost = 36111))), + cost = 36111, methodCostDetails(SHeader.ADProofsRootMethod, 10), 1786))), existingPropTest("ADProofsRoot", { (x: Header) => x.ADProofsRoot})) verifyCases( - Seq((h1, Expected(Success(CAvlTree(createAvlTreeData())), cost = 36092))), + Seq((h1, Expected(Success(CAvlTree(createAvlTreeData())), cost = 36092, methodCostDetails(SHeader.stateRootMethod, 10), 1785))), existingPropTest("stateRoot", { (x: Header) => x.stateRoot })) verifyCases( Seq((h1, Expected(Success( Helpers.decodeBytes("804101ff01000080a3ffbd006ac080098df132a7017f00649311ec0e00000100")), - cost = 36094))), + cost = 36094, methodCostDetails(SHeader.transactionsRootMethod, 10), 1786))), existingPropTest("transactionsRoot", { (x: Header) => x.transactionsRoot })) verifyCases( - Seq((h1, Expected(Success(1L), cost = 36151))), + Seq((h1, Expected(Success(1L), cost = 36151, methodCostDetails(SHeader.timestampMethod, 10), 1785))), existingPropTest("timestamp", { (x: Header) => x.timestamp })) verifyCases( - Seq((h1, Expected(Success(-1L), cost = 36125))), + Seq((h1, Expected(Success(-1L), cost = 36125, methodCostDetails(SHeader.nBitsMethod, 10), 1785))), existingPropTest("nBits", { (x: Header) => x.nBits })) verifyCases( - Seq((h1, Expected(Success(1), cost = 36134))), + Seq((h1, Expected(Success(1), cost = 36134, methodCostDetails(SHeader.heightMethod, 10), 1785))), existingPropTest("height", { (x: Header) => x.height })) verifyCases( Seq((h1, Expected(Success( Helpers.decodeBytes("e57f80885601b8ff348e01808000bcfc767f2dd37f0d01015030ec018080bc62")), - cost = 36133))), + cost = 36133, methodCostDetails(SHeader.extensionRootMethod, 10), 1786))), existingPropTest("extensionRoot", { (x: Header) => x.extensionRoot })) verifyCases( Seq((h1, Expected(Success( Helpers.decodeGroupElement("039bdbfa0b49cc6bef58297a85feff45f7bbeb500a9d2283004c74fcedd4bd2904")), - cost = 36111))), + cost = 36111, methodCostDetails(SHeader.minerPkMethod, 10), 1802))), existingPropTest("minerPk", { (x: Header) => x.minerPk })) verifyCases( Seq((h1, Expected(Success( Helpers.decodeGroupElement("0361299207fa392231e23666f6945ae3e867b978e021d8d702872bde454e9abe9c")), - cost = 36111))), + cost = 36111, methodCostDetails(SHeader.powOnetimePkMethod, 10), 1802))), existingPropTest("powOnetimePk", { (x: Header) => x.powOnetimePk })) verifyCases( Seq((h1, Expected(Success( Helpers.decodeBytes("7f4f09012a807f01")), - cost = 36176))), + cost = 36176, methodCostDetails(SHeader.powNonceMethod, 10), 1786))), existingPropTest("powNonce", { (x: Header) => x.powNonce })) verifyCases( Seq((h1, Expected(Success( CBigInt(new BigInteger("-e24990c47e15ed4d0178c44f1790cc72155d516c43c3e8684e75db3800a288", 16))), - cost = 36220))), + cost = 36220, methodCostDetails(SHeader.powDistanceMethod, 10), 1785))), existingPropTest("powDistance", { (x: Header) => x.powDistance })) verifyCases( Seq((h1, Expected(Success( Helpers.decodeBytes("7f0180")), - cost = 36100))), + cost = 36100, methodCostDetails(SHeader.votesMethod, 10), 1786))), existingPropTest("votes", { (x: Header) => x.votes })) } @@ -4465,9 +4874,17 @@ class SigmaDslSpecification extends SigmaDslTesting test(samples, existingPropTest("dataInputs", { (x: Context) => x.dataInputs })) + val testTraceBase = traceBase ++ Array( + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex) + ) + + val costDetails = TracedCost(testTraceBase) verifyCases( Seq( - (ctx, Expected(Success(dataBox), cost = 37087)), + (ctx, Expected(Success(dataBox), cost = 37087, costDetails, 1789)), (ctx.copy(_dataInputs = Coll()), Expected(new ArrayIndexOutOfBoundsException("0"))) ), existingFeature({ (x: Context) => x.dataInputs(0) }, @@ -4487,11 +4904,12 @@ class SigmaDslSpecification extends SigmaDslTesting )), preGeneratedSamples = Some(samples)) + val idCostDetails = TracedCost(testTraceBase :+ FixedCostItem(CompanionDesc(ExtractId), FixedCost(JitCost(12)))) verifyCases( Seq( (ctx, Expected(Success( Helpers.decodeBytes("7da4b55971f19a78d007638464580f91a020ab468c0dbe608deb1f619e245bc3")), - cost = 37193)) + cost = 37193, idCostDetails, 1792)) ), existingFeature({ (x: Context) => x.dataInputs(0).id }, "{ (x: Context) => x.dataInputs(0).id }", @@ -4541,16 +4959,39 @@ class SigmaDslSpecification extends SigmaDslTesting test(samples, existingFeature({ (x: Context) => x.SELF }, "{ (x: Context) => x.SELF }", FuncValue(Vector((1, SContext)), Self))) + val heightCostDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(Height) + ) + ) verifyCases( - Seq(ctx -> Expected(Success(ctx.HEIGHT), cost = 35885)), + Seq(ctx -> Expected(Success(ctx.HEIGHT), cost = 35885, heightCostDetails, 1786)), existingFeature( { (x: Context) => x.HEIGHT }, "{ (x: Context) => x.HEIGHT }", FuncValue(Vector((1, SContext)), Height)), preGeneratedSamples = Some(samples)) + val inputsCostDetails1 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(Inputs), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(MapCollection), PerItemCost(JitCost(20), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount))) verifyCases( - Seq((ctx, Expected(Success(Coll[Long](80946L)), cost = 39152))), + Seq((ctx, Expected(Success(Coll[Long](80946L)), cost = 39152, inputsCostDetails1, 1790))), existingFeature( { (x: Context) => x.INPUTS.map { (b: Box) => b.value } }, "{ (x: Context) => x.INPUTS.map { (b: Box) => b.value } }", @@ -4560,8 +5001,26 @@ class SigmaDslSpecification extends SigmaDslTesting )), preGeneratedSamples = Some(samples)) + val inputsCostDetails2 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(Inputs), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(MapCollection), PerItemCost(JitCost(20), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + FixedCostItem(Tuple))) verifyCases( - Seq((ctx, Expected(Success(Coll((80946L, 80946L))), cost = 39959))), + Seq((ctx, Expected(Success(Coll((80946L, 80946L))), cost = 39959, inputsCostDetails2, 1794))), existingFeature( { (x: Context) => x.INPUTS.map { (b: Box) => (b.value, b.value) } }, """{ (x: Context) => @@ -4616,14 +5075,20 @@ class SigmaDslSpecification extends SigmaDslTesting )), preGeneratedSamples = Some(samples)) + val selfCostDetails = TracedCost( + traceBase ++ Array( + FixedCostItem(PropertyCall), + FixedCostItem(SContext.selfBoxIndexMethod, FixedCost(JitCost(20))) + ) + ) verifyCases( Seq( (ctx, Expected( Success(-1), cost = 36318, - newDetails = CostDetails.ZeroCost, + expectedDetails = CostDetails.ZeroCost, newCost = 1786, newVersionedResults = { - val res = (ExpectedResult(Success(0), Some(1786)) -> None) + val res = (ExpectedResult(Success(0), Some(1786)) -> Some(selfCostDetails)) Seq(0, 1, 2).map(version => version -> res) })) ), @@ -4653,12 +5118,20 @@ class SigmaDslSpecification extends SigmaDslTesting } verifyCases( - Seq(ctx -> Expected(Success(ctx.LastBlockUtxoRootHash), cost = 35990)), + Seq(ctx -> Expected(Success(ctx.LastBlockUtxoRootHash), cost = 35990, methodCostDetails(SContext.lastBlockUtxoRootHashMethod, 15), 1786)), existingPropTest("LastBlockUtxoRootHash", { (x: Context) => x.LastBlockUtxoRootHash }), preGeneratedSamples = Some(samples)) + val isUpdateAllowedCostDetails = TracedCost( + traceBase ++ Array( + FixedCostItem(PropertyCall), + FixedCostItem(SContext.lastBlockUtxoRootHashMethod, FixedCost(JitCost(15))), + FixedCostItem(PropertyCall), + FixedCostItem(SAvlTree.isUpdateAllowedMethod, FixedCost(JitCost(15))) + ) + ) verifyCases( - Seq(ctx -> Expected(Success(ctx.LastBlockUtxoRootHash.isUpdateAllowed), cost = 36288)), + Seq(ctx -> Expected(Success(ctx.LastBlockUtxoRootHash.isUpdateAllowed), cost = 36288, isUpdateAllowedCostDetails, 1787)), existingFeature( { (x: Context) => x.LastBlockUtxoRootHash.isUpdateAllowed }, "{ (x: Context) => x.LastBlockUtxoRootHash.isUpdateAllowed }", @@ -4679,7 +5152,7 @@ class SigmaDslSpecification extends SigmaDslTesting preGeneratedSamples = Some(samples)) verifyCases( - Seq(ctx -> Expected(Success(ctx.minerPubKey), cost = 36047)), + Seq(ctx -> Expected(Success(ctx.minerPubKey), cost = 36047, methodCostDetails(SContext.minerPubKeyMethod, 20), 1787)), existingPropTest("minerPubKey", { (x: Context) => x.minerPubKey }), preGeneratedSamples = Some(samples)) @@ -4701,7 +5174,7 @@ class SigmaDslSpecification extends SigmaDslTesting "{ (x: Context) => getVar[Boolean](11) }", FuncValue(Vector((1, SContext)), GetVar(11.toByte, SOption(SBoolean)))), preGeneratedSamples = Some(samples)) - + verifyCases( Seq((ctx, Expected(new InvalidType("Cannot getVar[Int](11): invalid type of value Value(true) at id=2")))), existingFeature((x: Context) => x.getVar[Int](11).get, @@ -4709,8 +5182,17 @@ class SigmaDslSpecification extends SigmaDslTesting FuncValue(Vector((1, SContext)), OptionGet(GetVar(11.toByte, SOption(SInt))))), preGeneratedSamples = Some(samples)) + val getVarCostDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(GetVar), + FixedCostItem(OptionGet))) verifyCases( - Seq((ctx, Expected(Success(true), cost = 36750))), + Seq((ctx, Expected(Success(true), cost = 36750, getVarCostDetails, 1785))), existingFeature((x: Context) => x.getVar[Boolean](11).get, "{ (x: Context) => getVar[Boolean](11).get }", FuncValue(Vector((1, SContext)), OptionGet(GetVar(11.toByte, SOption(SBoolean))))), @@ -4720,9 +5202,31 @@ class SigmaDslSpecification extends SigmaDslTesting property("Conditional access to data box register using isDefined") { val (_, _, _, ctx, _, _) = contextData() + val registerIsDefinedCostDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(OptionGet) + ) + ) verifyCases( Seq( - ctx -> Expected(Success(-135729055492651903L), 38399) + ctx -> Expected(Success(-135729055492651903L), 38399, registerIsDefinedCostDetails, 1799) ), existingFeature( { (x: Context) => @@ -4782,7 +5286,11 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - ctx -> Expected(expectedError) + ctx -> Expected(Failure(expectedError), 0, CostDetails.ZeroCost, 1813, + newVersionedResults = { + Seq.tabulate(3)(v => v -> (ExpectedResult(Success(true), Some(1813)) -> None)) + } + ) ), changedFeature( scalaFunc = { (x: Context) => @@ -4855,14 +5363,103 @@ class SigmaDslSpecification extends SigmaDslTesting property("Conditional access OUTPUTS(0).R4 using tag in R5") { val (_, _, _, ctx, _, _) = contextData() + val registerTagCostDetails1 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(Outputs), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(OptionGet) + ) + ) + val registerTagCostDetails2 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(Outputs), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(OptionGet), + TypeBasedCostItem(Upcast, SLong) + ) + ) + + val registerTagCostDetails3 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(Outputs), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) verifyCases( Seq( - ctx -> Expected(Success(5008366408131208436L), 40406), + ctx -> Expected(Success(5008366408131208436L), 40406, registerTagCostDetails1, 1811), ctxWithRegsInOutput(ctx, Map( ErgoBox.R5 -> LongConstant(0L), - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(10L), 40396), + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(10L), 40396, registerTagCostDetails2, 1810), ctxWithRegsInOutput(ctx, Map( - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(-1L), 40396) + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(-1L), 40396, registerTagCostDetails3, 1797) ), existingFeature( { (x: Context) => @@ -4935,38 +5532,165 @@ class SigmaDslSpecification extends SigmaDslTesting property("Conditional access OUTPUTS(0).R4 using tag in R5 (plus action)") { val (_, _, _, ctx, _, _) = contextData() - verifyCases( - Seq( - // case 1L - ctx -> Expected(Success(5008366408131289382L), 41016), - // case 0L - ctxWithRegsInOutput(ctx, Map( - ErgoBox.R5 -> LongConstant(0L), - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(80956L), 41006), - - // case returning 0L - ctxWithRegsInOutput(ctx, Map( - ErgoBox.R5 -> LongConstant(2L), - // note R4 is required to avoid - // "RuntimeException: Set of non-mandatory indexes is not densely packed" - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(0L), 41006), - - // case returning -1L - ctxWithRegsInOutput(ctx, Map( - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(-1L), 41006) - ), - existingFeature( - { (x: Context) => - val tagOpt = x.OUTPUTS(0).R5[Long] - val res = if (tagOpt.isDefined) { - val tag = tagOpt.get - if (tag == 0L) { - val short = x.OUTPUTS(0).R4[Short].get // access Short in the register - short.toLong + x.SELF.value - } else { - if (tag == 1L) { - val long = x.OUTPUTS(0).R4[Long].get // access Long in the register - long + x.SELF.value + val tagRegisterCostDetails1 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(Outputs), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(OptionGet), + FixedCostItem(Self), + FixedCostItem(ExtractAmount), + TypeBasedCostItem(ArithOp.Plus, SLong) + ) + ) + val tagRegisterCostDetails2 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(Outputs), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(OptionGet), + TypeBasedCostItem(Upcast, SLong), + FixedCostItem(Self), + FixedCostItem(ExtractAmount), + TypeBasedCostItem(ArithOp.Plus, SLong) + ) + ) + val tagRegisterCostDetails3 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(Outputs), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) + val tagRegisterCostDetails4 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(Outputs), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) + verifyCases( + Seq( + // case 1L + ctx -> Expected(Success(5008366408131289382L), 41016, tagRegisterCostDetails1, 1814), + // case 0L + ctxWithRegsInOutput(ctx, Map( + ErgoBox.R5 -> LongConstant(0L), + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(80956L), 41006, tagRegisterCostDetails2, 1813), + + // case returning 0L + ctxWithRegsInOutput(ctx, Map( + ErgoBox.R5 -> LongConstant(2L), + // note R4 is required to avoid + // "RuntimeException: Set of non-mandatory indexes is not densely packed" + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(0L), 41006, tagRegisterCostDetails3, 1804), + + // case returning -1L + ctxWithRegsInOutput(ctx, Map( + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(-1L), 41006, tagRegisterCostDetails4, 1797) + ), + existingFeature( + { (x: Context) => + val tagOpt = x.OUTPUTS(0).R5[Long] + val res = if (tagOpt.isDefined) { + val tag = tagOpt.get + if (tag == 0L) { + val short = x.OUTPUTS(0).R4[Short].get // access Short in the register + short.toLong + x.SELF.value + } else { + if (tag == 1L) { + val long = x.OUTPUTS(0).R4[Long].get // access Long in the register + long + x.SELF.value } else 0L } @@ -5037,19 +5761,149 @@ class SigmaDslSpecification extends SigmaDslTesting property("Conditional access dataInputs(0).R4 using tag in R5") { val (_, _, _, ctx, _, _) = contextData() + val tagRegisterCostDetails1 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(OptionGet) + ) + ) + val tagRegisterCostDetails2 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(OptionGet), + TypeBasedCostItem(Upcast, SLong) + ) + ) + val tagRegisterCostDetails3 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) + val tagRegisterCostDetails4 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) + verifyCases( Seq( ctxWithRegsInDataInput(ctx, Map( ErgoBox.R5 -> LongConstant(1L), - ErgoBox.R4 -> LongConstant(10))) -> Expected(Success(10L), 41084), + ErgoBox.R4 -> LongConstant(10))) -> Expected(Success(10L), 41084, tagRegisterCostDetails1, 1812), ctxWithRegsInDataInput(ctx, Map( ErgoBox.R5 -> LongConstant(0L), - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(10L), 41084), + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(10L), 41084, tagRegisterCostDetails2, 1811), ctxWithRegsInDataInput(ctx, Map( ErgoBox.R5 -> LongConstant(2L), - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(0L), 41084), + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(0L), 41084, tagRegisterCostDetails3, 1806), ctxWithRegsInDataInput(ctx, Map( - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(-1L), 41084) + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(-1L), 41084, tagRegisterCostDetails4, 1799) ), existingFeature( { (x: Context) => @@ -5135,19 +5989,154 @@ class SigmaDslSpecification extends SigmaDslTesting property("Conditional access dataInputs(0).R4 using tag in R5 (plus action)") { val (_, _, _, ctx, _, _) = contextData() + val costDetails1 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(OptionGet), + FixedCostItem(Self), + FixedCostItem(ExtractAmount), + TypeBasedCostItem(ArithOp.Plus, SLong) + ) + ) + val costDetails2 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(OptionGet), + TypeBasedCostItem(Upcast, SLong), + FixedCostItem(Self), + FixedCostItem(ExtractAmount), + TypeBasedCostItem(ArithOp.Plus, SLong) + ) + ) + val costDetails3 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) + val costDetails4 = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.dataInputsMethod, FixedCost(JitCost(15))), + FixedCostItem(Constant), + FixedCostItem(ByIndex), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractRegisterAs), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) verifyCases( Seq( ctxWithRegsInDataInput(ctx, Map( ErgoBox.R5 -> LongConstant(1L), - ErgoBox.R4 -> LongConstant(10))) -> Expected(Success(80956L), 41694), + ErgoBox.R4 -> LongConstant(10))) -> Expected(Success(80956L), 41694, costDetails1, 1816), ctxWithRegsInDataInput(ctx, Map( ErgoBox.R5 -> LongConstant(0L), - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(80956L), 41694), + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(80956L), 41694, costDetails2, 1814), ctxWithRegsInDataInput(ctx, Map( ErgoBox.R5 -> LongConstant(2L), - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(0L), 41694), + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(0L), 41694, costDetails3, 1806), ctxWithRegsInDataInput(ctx, Map( - ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(-1L), 41694) + ErgoBox.R4 -> ShortConstant(10))) -> Expected(Success(-1L), 41694, costDetails4, 1799) ), existingFeature( { (x: Context) => @@ -5244,40 +6233,36 @@ class SigmaDslSpecification extends SigmaDslTesting } property("xorOf equivalence") { + def costDetails(i: Int) = TracedCost(traceBase :+ SeqCostItem(CompanionDesc(XorOf), PerItemCost(JitCost(20), JitCost(5), 32), i)) verifyCases( { - def success[T](v: T, c: Int) = Expected(Success(v), c) - def successNew[T](v: T, c: Int, newV: T, newC: Int) = Expected( + def successNew[T](v: T, c: Int, newV: T, cd: CostDetails) = Expected( value = Success(v), cost = c, - newDetails = CostDetails.ZeroCost, - newCost = newC, - newVersionedResults = Seq( - 0 -> (ExpectedResult(Success(newV), Some(newC)) -> None), - 1 -> (ExpectedResult(Success(newV), Some(newC)) -> None), - 2 -> (ExpectedResult(Success(newV), Some(newC)) -> None) - )) - val newCost = 1786 + expectedDetails = CostDetails.ZeroCost, + newCost = 1786, + newVersionedResults = Seq(0, 1, 2).map(i => i -> (ExpectedResult(Success(newV), Some(1786)) -> Some(cd))) + ) Seq( - (Coll[Boolean](), successNew(false, 37061, newV = false, newCost)), - (Coll[Boolean](false), successNew(false, 37071, newV = false, newCost)), - (Coll[Boolean](true), successNew(false, 37071, newV = true, newCost)), - (Coll[Boolean](false, false), successNew(false, 37081, newV = false, newCost)), - (Coll[Boolean](false, true), successNew(true, 37081, newV = true, newCost)), - (Coll[Boolean](true, false), successNew(true, 37081, newV = true, newCost)), - (Coll[Boolean](true, true), successNew(false, 37081, newV = false, newCost)), - (Coll[Boolean](false, false, false), successNew(false, 37091, newV = false, newCost)), - (Coll[Boolean](false, false, true), successNew(true, 37091, newV = true, newCost)), - (Coll[Boolean](false, true, false), successNew(true, 37091, newV = true, newCost)), - (Coll[Boolean](false, true, true), successNew(true, 37091, newV = false, newCost)), - (Coll[Boolean](true, false, false), successNew(true, 37091, newV = true, newCost)), - (Coll[Boolean](true, false, true), successNew(true, 37091, newV = false, newCost)), - (Coll[Boolean](true, true, false), successNew(true, 37091, newV = false, newCost)), - (Coll[Boolean](true, true, true), successNew(false, 37091, newV = true, newCost)), - (Coll[Boolean](false, false, false, false), successNew(false, 37101, newV = false, newCost)), - (Coll[Boolean](false, false, false, true), successNew(true, 37101, newV = true, newCost)), - (Coll[Boolean](false, false, true, false), successNew(true, 37101, newV = true, newCost)), - (Coll[Boolean](false, false, true, true), successNew(true, 37101, newV = false, newCost)) + (Coll[Boolean](), successNew(false, 37061, newV = false, costDetails(0))), + (Coll[Boolean](false), successNew(false, 37071, newV = false, costDetails(1))), + (Coll[Boolean](true), successNew(false, 37071, newV = true, costDetails(1))), + (Coll[Boolean](false, false), successNew(false, 37081, newV = false, costDetails(2))), + (Coll[Boolean](false, true), successNew(true, 37081, newV = true, costDetails(2))), + (Coll[Boolean](true, false), successNew(true, 37081, newV = true, costDetails(2))), + (Coll[Boolean](true, true), successNew(false, 37081, newV = false, costDetails(2))), + (Coll[Boolean](false, false, false), successNew(false, 37091, newV = false, costDetails(3))), + (Coll[Boolean](false, false, true), successNew(true, 37091, newV = true, costDetails(3))), + (Coll[Boolean](false, true, false), successNew(true, 37091, newV = true, costDetails(3))), + (Coll[Boolean](false, true, true), successNew(true, 37091, newV = false, costDetails(3))), + (Coll[Boolean](true, false, false), successNew(true, 37091, newV = true, costDetails(3))), + (Coll[Boolean](true, false, true), successNew(true, 37091, newV = false, costDetails(3))), + (Coll[Boolean](true, true, false), successNew(true, 37091, newV = false, costDetails(3))), + (Coll[Boolean](true, true, true), successNew(false, 37091, newV = true, costDetails(3))), + (Coll[Boolean](false, false, false, false), successNew(false, 37101, newV = false, costDetails(4))), + (Coll[Boolean](false, false, false, true), successNew(true, 37101, newV = true, costDetails(4))), + (Coll[Boolean](false, false, true, false), successNew(true, 37101, newV = true, costDetails(4))), + (Coll[Boolean](false, false, true, true), successNew(true, 37101, newV = false, costDetails(4))) ) }, changedFeature( @@ -5288,27 +6273,32 @@ class SigmaDslSpecification extends SigmaDslTesting } property("LogicalNot equivalence") { + val costDetails = TracedCost(traceBase :+ FixedCostItem(LogicalNot)) verifyCases( Seq( - (true, Expected(Success(false), 35864)), - (false, Expected(Success(true), 35864))), + (true, Expected(Success(false), 35864, costDetails, 1785)), + (false, Expected(Success(true), 35864, costDetails, 1785))), existingFeature((x: Boolean) => !x, "{ (x: Boolean) => !x }", FuncValue(Vector((1, SBoolean)), LogicalNot(ValUse(1, SBoolean))))) } property("Numeric Negation equivalence") { + val costDetails = TracedCost(traceBase :+ FixedCostItem(Negation)) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36136) + def success[T](v: T) = Expected(Success(v), 36136, costDetails, 1786) Seq( (Byte.MinValue, success(Byte.MinValue)), // !!! + ((Byte.MinValue + 1).toByte, success(Byte.MaxValue)), (-40.toByte, success(40.toByte)), (-1.toByte, success(1.toByte)), (0.toByte, success(0.toByte)), (1.toByte, success(-1.toByte)), (45.toByte, success(-45.toByte)), - (127.toByte, success(-127.toByte))) + (127.toByte, success(-127.toByte)), + (Byte.MaxValue, success(-127.toByte)) + ) }, existingFeature((x: Byte) => (-x).toByte, "{ (x: Byte) => -x }", @@ -5316,15 +6306,16 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36136) + def success[T](v: T) = Expected(Success(v), 36136, costDetails, 1786) Seq( (Short.MinValue, success(Short.MinValue)), // special case! - ((Short.MinValue + 1).toShort, success(32767.toShort)), + ((Short.MinValue + 1).toShort, success(Short.MaxValue)), (-1528.toShort, success(1528.toShort)), (-1.toShort, success(1.toShort)), (0.toShort, success(0.toShort)), (1.toShort, success(-1.toShort)), (7586.toShort, success(-7586.toShort)), + (32767.toShort, success(-32767.toShort)), (Short.MaxValue, success(-32767.toShort))) }, existingFeature((x: Short) => (-x).toShort, @@ -5333,10 +6324,10 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36136) + def success[T](v: T) = Expected(Success(v), 36136, costDetails, 1786) Seq( (Int.MinValue, success(Int.MinValue)), // special case! - (Int.MinValue + 1, success(2147483647)), + (Int.MinValue + 1, success(Int.MaxValue)), (-63509744, success(63509744)), (-1, success(1)), (0, success(0)), @@ -5350,16 +6341,16 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36136) + def success[T](v: T) = Expected(Success(v), 36136, costDetails, 1786) Seq( (Long.MinValue, success(Long.MinValue)), // special case! - (Long.MinValue + 1, success(9223372036854775807L)), + (Long.MinValue + 1, success(Long.MaxValue)), (-957264171003115006L, success(957264171003115006L)), (-1L, success(1L)), (0L, success(0L)), (1L, success(-1L)), (340835904095777627L, success(-340835904095777627L)), - (9223372036854775807L, success(-9223372036854775807L))) + (Long.MaxValue, success(-9223372036854775807L))) }, existingFeature((x: Long) => -x, "{ (x: Long) => -x }", @@ -5367,7 +6358,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36136) + def success[T](v: T) = Expected(Success(v), 36136, costDetails, 1787) Seq( (CBigInt(new BigInteger("-1655a05845a6ad363ac88ea21e88b97e436a1f02c548537e12e2d9667bf0680", 16)), success(CBigInt(new BigInteger("1655a05845a6ad363ac88ea21e88b97e436a1f02c548537e12e2d9667bf0680", 16)))), (CBigInt(new BigInteger("-1b24ba8badba8abf347cce054d9b9f14f229321507245b8", 16)), success(CBigInt(new BigInteger("1b24ba8badba8abf347cce054d9b9f14f229321507245b8", 16)))), @@ -5391,9 +6382,21 @@ class SigmaDslSpecification extends SigmaDslTesting } property("groupGenerator equivalence") { + val costDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(Global), + FixedCostItem(PropertyCall), + FixedCostItem(SGlobal.groupGeneratorMethod, FixedCost(JitCost(10))) + ) + ) verifyCases( { - def success[T](v: T) = Expected(Success(v), 35981) + def success[T](v: T) = Expected(Success(v), 35981, costDetails, 1802) Seq( (-1, success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), (1, success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")))) @@ -5412,7 +6415,7 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 35981) + def success[T](v: T) = Expected(Success(v), 35981, costDetails, 1802) Seq( (-1, success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), (1, success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")))) @@ -5430,9 +6433,15 @@ class SigmaDslSpecification extends SigmaDslTesting ))) if (lowerMethodCallsInTests) { + val expCostDetails = TracedCost( + costDetails.trace ++ Array( + FixedCostItem(ValUse), + FixedCostItem(Exponentiate) + ) + ) verifyCases( { - def success[T](v: T) = Expected(Success(v), 41237) + def success[T](v: T) = Expected(Success(v), 41237, expCostDetails, 1892) Seq( (CBigInt(new BigInteger("-e5c1a54694c85d644fa30a6fc5f3aa209ed304d57f72683a0ebf21038b6a9d", 16)), success(Helpers.decodeGroupElement("023395bcba3d7cf21d73c50f8af79d09a8c404c15ce9d04f067d672823bae91a54"))), (CBigInt(new BigInteger("-bc2d08f935259e0eebf272c66c6e1dbd484c6706390215", 16)), success(Helpers.decodeGroupElement("02ddcf4c48105faf3c16f7399b5dbedd82ab0bb50ae292d8f88f49a3f86e78974e"))), @@ -5466,29 +6475,36 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Global.xor equivalence") { - if (lowerMethodCallsInTests) { + def costDetails(i: Int) = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + SeqCostItem(CompanionDesc(Xor), PerItemCost(JitCost(10), JitCost(2), 128), i) + ) + ) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36903) + def success[T](v: T, cd: CostDetails) = Expected(Success(v), 36903, cd, 1789) Seq( - ((Helpers.decodeBytes(""), Helpers.decodeBytes("")), success(Helpers.decodeBytes(""))), - ((Helpers.decodeBytes("01"), Helpers.decodeBytes("01")), success(Helpers.decodeBytes("00"))), - ((Helpers.decodeBytes("0100"), Helpers.decodeBytes("0101")), success(Helpers.decodeBytes("0001"))), - ((Helpers.decodeBytes("01"), Helpers.decodeBytes("0101")), success(Helpers.decodeBytes("00"))), + ((Helpers.decodeBytes(""), Helpers.decodeBytes("")), success(Helpers.decodeBytes(""), costDetails(0))), + ((Helpers.decodeBytes("01"), Helpers.decodeBytes("01")), success(Helpers.decodeBytes("00"), costDetails(1))), + ((Helpers.decodeBytes("0100"), Helpers.decodeBytes("0101")), success(Helpers.decodeBytes("0001"), costDetails(2))), + ((Helpers.decodeBytes("01"), Helpers.decodeBytes("0101")), success(Helpers.decodeBytes("00"), costDetails(1))), ((Helpers.decodeBytes("0100"), Helpers.decodeBytes("01")) -> Expected(Failure(new ArrayIndexOutOfBoundsException("1")), cost = 0, - newDetails = CostDetails.ZeroCost, + expectedDetails = CostDetails.ZeroCost, newCost = 1789, newVersionedResults = { - val res = (ExpectedResult(Success(Helpers.decodeBytes("00")), Some(1789)), None) + val res = (ExpectedResult(Success(Helpers.decodeBytes("00")), Some(1789)), Some(costDetails(1))) Seq(0, 1, 2).map(version => version -> res) } )), ((Helpers.decodeBytes("800136fe89afff802acea67128a0ff007fffe3498c8001806080012b"), Helpers.decodeBytes("648018010a5d5800f5b400a580e7b4809b0cd273ff1230bfa800017f7fdb002749b3ac2b86ff")), - success(Helpers.decodeBytes("e4812eff83f2a780df7aa6d4a8474b80e4f3313a7392313fc8800054"))) + success(Helpers.decodeBytes("e4812eff83f2a780df7aa6d4a8474b80e4f3313a7392313fc8800054"), costDetails(28))) ) }, changedFeature( @@ -5524,11 +6540,23 @@ class SigmaDslSpecification extends SigmaDslTesting Success(Helpers.decodeBytes("00")), Some(116) ) - Seq( // expected result for each version - 0 -> ( res -> None ), - 1 -> ( res -> None ), - 2 -> ( res -> None ) + val details = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(Global), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + SeqCostItem(CompanionDesc(Xor), PerItemCost(JitCost(10), JitCost(2), 128), 1) + ) ) + Seq.tabulate(3)(v => v -> ( res -> Some(details) )) // expected result for each version } ) ) @@ -5625,13 +6653,46 @@ class SigmaDslSpecification extends SigmaDslTesting val b1 = create_b1 val b2 = create_b2 + val costDetails = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Filter), PerItemCost(JitCost(20), JitCost(1), 10), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Filter), PerItemCost(JitCost(20), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Filter), PerItemCost(JitCost(20), JitCost(1), 10), 2), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong) + ) + ) verifyCases( { - def success[T](v: T, c: Int) = Expected(Success(v), c) + def success[T](v: T, c: Int, costDetails: CostDetails, newCost: Int) = Expected(Success(v), c, costDetails, newCost) Seq( - (Coll[Box](), success(Coll[Box](), 37297)), - (Coll[Box](b1), success(Coll[Box](), 37397)), - (Coll[Box](b1, b2), success(Coll[Box](b2), 37537)) + (Coll[Box](), success(Coll[Box](), 37297, costDetails, 1787)), + (Coll[Box](b1), success(Coll[Box](), 37397, costDetails2, 1792)), + (Coll[Box](b1, b2), success(Coll[Box](b2), 37537, costDetails3, 1796)) ) }, existingFeature({ (x: Coll[Box]) => x.filter({ (b: Box) => b.value > 1 }) }, @@ -5651,17 +6712,46 @@ class SigmaDslSpecification extends SigmaDslTesting val b1 = create_b1 val b2 = create_b2 + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + SeqCostItem(MethodDesc(SCollection.FlatMapMethod), PerItemCost(JitCost(60), JitCost(10), 8), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractScriptBytes), + SeqCostItem(MethodDesc(SCollection.FlatMapMethod), PerItemCost(JitCost(60), JitCost(10), 8), 135) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractScriptBytes), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractScriptBytes), + SeqCostItem(MethodDesc(SCollection.FlatMapMethod), PerItemCost(JitCost(60), JitCost(10), 8), 147) + ) + ) verifyCases( { - def success[T](v: T, c: Int) = Expected(Success(v), c) Seq( - (Coll[Box](), success(Coll[Byte](), 38126)), - (Coll[Box](b1), success(Helpers.decodeBytes( + (Coll[Box](), Expected(Success(Coll[Byte]()), 38126, costDetails1, 1793)), + (Coll[Box](b1), Expected(Success(Helpers.decodeBytes( "0008ce02c1a9311ecf1e76c787ba4b1c0e10157b4f6d1e4db3ef0d84f411c99f2d4d2c5b027d1bd9a437e73726ceddecc162e5c85f79aee4798505bc826b8ad1813148e4190257cff6d06fe15d1004596eeb97a7f67755188501e36adc49bd807fe65e9d8281033c6021cff6ba5fdfc4f1742486030d2ebbffd9c9c09e488792f3102b2dcdabd5" - ), 38206)), - (Coll[Box](b1, b2), success(Helpers.decodeBytes( + )), 38206, costDetails2, 1811)), + (Coll[Box](b1, b2), Expected(Success(Helpers.decodeBytes( "0008ce02c1a9311ecf1e76c787ba4b1c0e10157b4f6d1e4db3ef0d84f411c99f2d4d2c5b027d1bd9a437e73726ceddecc162e5c85f79aee4798505bc826b8ad1813148e4190257cff6d06fe15d1004596eeb97a7f67755188501e36adc49bd807fe65e9d8281033c6021cff6ba5fdfc4f1742486030d2ebbffd9c9c09e488792f3102b2dcdabd500d197830201010096850200" - ), 38286)) + )), 38286, costDetails3, 1815)) ) }, existingFeature({ (x: Coll[Box]) => x.flatMap({ (b: Box) => b.propositionBytes }) }, @@ -5684,14 +6774,21 @@ class SigmaDslSpecification extends SigmaDslTesting val samples = sampleCollBoxes val b1 = create_b1 val b2 = create_b2 + def costDetails(zipElements: Int) = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + SeqCostItem(MethodDesc(SCollection.ZipMethod), PerItemCost(JitCost(10), JitCost(1), 10), zipElements) + ) + ) verifyCases( { - def success[T](v: T, c: Int) = Expected(Success(v), c) + def success[T](v: T, c: Int, cd: CostDetails, nc: Int) = Expected(Success(v), c, cd, nc) Seq( - (Coll[Box](), success(Coll[(Box, Box)](), 37399)), - (Coll[Box](b1), success(Coll[(Box, Box)]((b1, b1)), 37559)), - (Coll[Box](b1, b2), success(Coll[(Box, Box)]((b1, b1), (b2, b2)), 37719)) + (Coll[Box](), success(Coll[(Box, Box)](), 37399, costDetails(0), 1786)), + (Coll[Box](b1), success(Coll[(Box, Box)]((b1, b1)), 37559, costDetails(1), 1788)), + (Coll[Box](b1, b2), success(Coll[(Box, Box)]((b1, b1), (b2, b2)), 37719, costDetails(2), 1790)) ) }, existingFeature({ (x: Coll[Box]) => x.zip(x) }, @@ -5714,9 +6811,10 @@ class SigmaDslSpecification extends SigmaDslTesting val samples = sampleCollBoxes val b1 = create_b1 val b2 = create_b2 + val costDetails = TracedCost(traceBase :+ FixedCostItem(SizeOf)) verifyCases( { - def success[T](v: T) = Expected(Success(v), 35954) + def success[T](v: T) = Expected(Success(v), 35954, costDetails, 1785) Seq( (Coll[Box](), success(0)), (Coll[Box](b1), success(1)), @@ -5733,13 +6831,19 @@ class SigmaDslSpecification extends SigmaDslTesting val samples = sampleCollBoxes val b1 = create_b1 val b2 = create_b2 + def costDetails(indicesCount: Int) = TracedCost( + traceBase ++ Array( + FixedCostItem(PropertyCall), + SeqCostItem(MethodDesc(SCollection.IndicesMethod), PerItemCost(JitCost(20), JitCost(2), 16), indicesCount) + ) + ) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36036) + def success[T](v: T, i: Int) = Expected(Success(v), 36036, costDetails(i), 1788) Seq( - (Coll[Box](), success(Coll[Int]())), - (Coll[Box](b1), success(Coll[Int](0))), - (Coll[Box](b1, b2), success(Coll[Int](0, 1))) + (Coll[Box](), success(Coll[Int](), 0)), + (Coll[Box](b1), success(Coll[Int](0), 1)), + (Coll[Box](b1, b2), success(Coll[Int](0, 1), 2)) ) }, existingFeature({ (x: Coll[Box]) => x.indices }, @@ -5761,15 +6865,42 @@ class SigmaDslSpecification extends SigmaDslTesting val samples = sampleCollBoxes val b1 = create_b1 val b2 = create_b2 + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(ForAll), PerItemCost(JitCost(3), JitCost(1), 10), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(ForAll), PerItemCost(JitCost(3), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(ForAll), PerItemCost(JitCost(3), JitCost(1), 10), 2), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong) + ) + ) - def success[T](v: T, c: Int) = Expected(Success(v), c) if (lowerMethodCallsInTests) { verifyCases( { Seq( - (Coll[Box](), success(true, 37909)), - (Coll[Box](b1), success(false, 37969)), - (Coll[Box](b1, b2), success(false, 38029)) + (Coll[Box](), Expected(Success(true), 37909, costDetails1, 1784)), + (Coll[Box](b1), Expected(Success(false), 37969, costDetails2, 1789)), + (Coll[Box](b1, b2), Expected(Success(false), 38029, costDetails3, 1789)) ) }, existingFeature({ (x: Coll[Box]) => x.forall({ (b: Box) => b.value > 1 }) }, @@ -5785,7 +6916,7 @@ class SigmaDslSpecification extends SigmaDslTesting } else { assertExceptionThrown( verifyCases( - Seq( (Coll[Box](), success(true, 37909)) ), + Seq( (Coll[Box](), Expected(Success(true), 37909)) ), existingFeature( { (x: Coll[Box]) => x.forall({ (b: Box) => b.value > 1 }) }, "{ (x: Coll[Box]) => x.forall({(b: Box) => b.value > 1 }) }" @@ -5799,15 +6930,47 @@ class SigmaDslSpecification extends SigmaDslTesting val samples = sampleCollBoxes val b1 = create_b1 val b2 = create_b2 + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Exists), PerItemCost(JitCost(3), JitCost(1), 10), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Exists), PerItemCost(JitCost(3), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Exists), PerItemCost(JitCost(3), JitCost(1), 10), 2), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(ExtractAmount), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong) + ) + ) - def success[T](v: T, c: Int) = Expected(Success(v), c) if (lowerMethodCallsInTests) { verifyCases( { Seq( - (Coll[Box](), success(false, 38455)), - (Coll[Box](b1), success(false, 38515)), - (Coll[Box](b1, b2), success(true, 38575)) + (Coll[Box](), Expected(Success(false), 38455, costDetails1, 1784)), + (Coll[Box](b1), Expected(Success(false), 38515, costDetails2, 1789)), + (Coll[Box](b1, b2), Expected(Success(true), 38575, costDetails3, 1793)) ) }, existingFeature({ (x: Coll[Box]) => x.exists({ (b: Box) => b.value > 1 }) }, @@ -5823,7 +6986,7 @@ class SigmaDslSpecification extends SigmaDslTesting } else { assertExceptionThrown( verifyCases( - Seq( (Coll[Box](), success(false, 38455)) ), + Seq( (Coll[Box](), Expected(Success(false), 38455)) ), existingFeature( { (x: Coll[Box]) => x.exists({ (b: Box) => b.value > 1 }) }, "{ (x: Coll[Box]) => x.exists({(b: Box) => b.value > 1 }) }" @@ -5835,16 +6998,68 @@ class SigmaDslSpecification extends SigmaDslTesting property("Coll exists with nested If") { val o = NumericOps.BigIntIsExactOrdering - def success[T](v: T, c: Int) = Expected(Success(v), c) + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Exists), PerItemCost(JitCost(3), JitCost(1), 10), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Exists), PerItemCost(JitCost(3), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SBigInt), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Exists), PerItemCost(JitCost(3), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SBigInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(LT, SBigInt) + ) + ) + val costDetails4 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Exists), PerItemCost(JitCost(3), JitCost(1), 10), 2), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SBigInt), + FixedCostItem(If), + FixedCostItem(Constant), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SBigInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(LT, SBigInt) + ) + ) + if (lowerMethodCallsInTests) { verifyCases( { Seq( - (Coll[BigInt](), success(false, 38955)), - (Coll[BigInt](BigIntZero), success(false, 39045)), - (Coll[BigInt](BigIntOne), success(true, 39045)), - (Coll[BigInt](BigIntZero, BigIntOne), success(true, 39135)), - (Coll[BigInt](BigIntZero, BigInt10), success(false, 39135)) + (Coll[BigInt](), Expected(Success(false), 38955, costDetails1, 1784)), + (Coll[BigInt](BigIntZero), Expected(Success(false), 39045, costDetails2, 1789)), + (Coll[BigInt](BigIntOne), Expected(Success(true), 39045, costDetails3, 1792)), + (Coll[BigInt](BigIntZero, BigIntOne), Expected(Success(true), 39135, costDetails4, 1797)), + (Coll[BigInt](BigIntZero, BigInt10), Expected(Success(false), 39135, costDetails4, 1797)) ) }, existingFeature( @@ -5870,7 +7085,7 @@ class SigmaDslSpecification extends SigmaDslTesting } else { assertExceptionThrown( verifyCases( - Seq( (Coll[BigInt](), success(false, 38955)) ), + Seq( (Coll[BigInt](), Expected(Success(false), 38955)) ), existingFeature( { (x: Coll[BigInt]) => x.exists({ (b: BigInt) => if (o.gt(b, BigIntZero)) o.lt(b, BigInt10) else false @@ -5885,16 +7100,69 @@ class SigmaDslSpecification extends SigmaDslTesting property("Coll forall with nested If") { val o = NumericOps.BigIntIsExactOrdering - def success[T](v: T, c: Int) = Expected(Success(v), c) + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(ForAll), PerItemCost(JitCost(3), JitCost(1), 10), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(ForAll), PerItemCost(JitCost(3), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GE, SBigInt), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(ForAll), PerItemCost(JitCost(3), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GE, SBigInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(LE, SBigInt) + ) + ) + val costDetails4 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(ForAll), PerItemCost(JitCost(3), JitCost(1), 10), 2), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GE, SBigInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(LE, SBigInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GE, SBigInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(LE, SBigInt) + ) + ) if (lowerMethodCallsInTests) { verifyCases( { Seq( - (Coll[BigInt](), success(true, 38412)), - (Coll[BigInt](BigIntMinusOne), success(false, 38502)), - (Coll[BigInt](BigIntOne), success(true, 38502)), - (Coll[BigInt](BigIntZero, BigIntOne), success(true, 38592)), - (Coll[BigInt](BigIntZero, BigInt11), success(false, 38592)) + (Coll[BigInt](), Expected(Success(true), 38412, costDetails1, 1784)), + (Coll[BigInt](BigIntMinusOne), Expected(Success(false), 38502, costDetails2, 1789)), + (Coll[BigInt](BigIntOne), Expected(Success(true), 38502, costDetails3, 1792)), + (Coll[BigInt](BigIntZero, BigIntOne), Expected(Success(true), 38592, costDetails4, 1799)), + (Coll[BigInt](BigIntZero, BigInt11), Expected(Success(false), 38592, costDetails4, 1799)) ) }, existingFeature( @@ -5920,7 +7188,7 @@ class SigmaDslSpecification extends SigmaDslTesting } else { assertExceptionThrown( verifyCases( - Seq( (Coll[BigInt](), success(true, 38412)) ), + Seq( (Coll[BigInt](), Expected(Success(true), 38412)) ), existingFeature( { (x: Coll[BigInt]) => x.forall({ (b: BigInt) => if (o.gteq(b, BigIntZero)) o.lteq(b, BigInt10) else false @@ -5940,24 +7208,100 @@ class SigmaDslSpecification extends SigmaDslTesting r <- Gen.choose(l, arr.length - 1) } yield (arr, (l, r)) property("Coll flatMap method equivalence") { + val costDetails0 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + SeqCostItem(MethodDesc(SCollection.FlatMapMethod), PerItemCost(JitCost(60), JitCost(10), 8), 0) + ) + ) + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(NamedDesc("MatchSingleArgMethodCall"), FixedCost(JitCost(30))), + SeqCostItem(NamedDesc("CheckFlatmapBody"), PerItemCost(JitCost(20), JitCost(20), 1), 1), + SeqCostItem(MethodDesc(SCollection.FlatMapMethod), PerItemCost(JitCost(60), JitCost(10), 8), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SGroupElement.GetEncodedMethod, FixedCost(JitCost(250))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SGroupElement.GetEncodedMethod, FixedCost(JitCost(250))), + SeqCostItem(MethodDesc(SCollection.FlatMapMethod), PerItemCost(JitCost(60), JitCost(10), 8), 66) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SGroupElement.GetEncodedMethod, FixedCost(JitCost(250))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SGroupElement.GetEncodedMethod, FixedCost(JitCost(250))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SGroupElement.GetEncodedMethod, FixedCost(JitCost(250))), + SeqCostItem(MethodDesc(SCollection.FlatMapMethod), PerItemCost(JitCost(60), JitCost(10), 8), 99) + ) + ) + val costDetails4 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SGroupElement.GetEncodedMethod, FixedCost(JitCost(250))), + FixedCostItem(PropertyCall), + SeqCostItem(MethodDesc(SCollection.IndicesMethod), PerItemCost(JitCost(20), JitCost(2), 16), 33), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SGroupElement.GetEncodedMethod, FixedCost(JitCost(250))), + FixedCostItem(PropertyCall), + SeqCostItem(MethodDesc(SCollection.IndicesMethod), PerItemCost(JitCost(20), JitCost(2), 16), 33), + SeqCostItem(MethodDesc(SCollection.FlatMapMethod), PerItemCost(JitCost(60), JitCost(10), 8), 66) + ) + ) + verifyCases( { - def success[T](v: T, c: Int) = Expected(Success(v), c) + def success[T](v: T, c: Int, cd: CostDetails, newCost: Int) = Expected(Success(v), c, cd, newCost) Seq( - Coll[GroupElement]() -> success(Coll[Byte](), 40133), + Coll[GroupElement]() -> Expected(Success(Coll[Byte]()), 40133, CostDetails.ZeroCost, 1794, + newVersionedResults = { + val res = ExpectedResult(Success(Coll[Byte]()), Some(1793)) + Seq.tabulate(3)(v => + v -> (res -> Some(costDetails0)) + ) + }), Coll[GroupElement]( Helpers.decodeGroupElement("02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee587"), Helpers.decodeGroupElement("0390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa")) -> success(Helpers.decodeBytes( "02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee5870390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa" - ), 40213), + ), 40213, costDetails2, 1854), Coll[GroupElement]( Helpers.decodeGroupElement("02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee587"), Helpers.decodeGroupElement("0390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa"), Helpers.decodeGroupElement("03bd839b969b02d218fd1192f2c80cbda9c6ce9c7ddb765f31b748f4666203df85")) -> success(Helpers.decodeBytes( "02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee5870390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa03bd839b969b02d218fd1192f2c80cbda9c6ce9c7ddb765f31b748f4666203df85" - ), 40253) + ), 40253, costDetails3, 1884) ) }, existingFeature( @@ -5991,7 +7335,7 @@ class SigmaDslSpecification extends SigmaDslTesting Helpers.decodeGroupElement("02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee587"), Helpers.decodeGroupElement("0390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa") ) -> Expected(Try(SCollection.throwInvalidFlatmap(null)), 0, - newDetails = CostDetails.ZeroCost, + expectedDetails = CostDetails.ZeroCost, newCost = 0, newVersionedResults = (0 to 2).map(version => // successful result for each version @@ -5999,16 +7343,14 @@ class SigmaDslSpecification extends SigmaDslTesting val is = Coll((0 to 32):_*) is.append(is) }), - verificationCost = Some(817)) -> None) + verificationCost = Some(817)) -> Some(costDetails4)) )) ) val f = changedFeature( - { (x: Coll[GroupElement]) => SCollection.throwInvalidFlatmap(null) }, - { (x: Coll[GroupElement]) => - if (VersionContext.current.isJitActivated) - x.flatMap({ (b: GroupElement) => b.getEncoded.indices }) - else - SCollection.throwInvalidFlatmap(null) + scalaFunc = { (x: Coll[GroupElement]) => SCollection.throwInvalidFlatmap(null) }, + scalaFuncNew = { (x: Coll[GroupElement]) => + // NOTE, v5.0 interpreter accepts any lambda in flatMap + x.flatMap({ (b: GroupElement) => b.getEncoded.indices }) }, "", // NOTE, the script for this test case cannot be compiled FuncValue( @@ -6043,18 +7385,7 @@ class SigmaDslSpecification extends SigmaDslTesting allowDifferentErrors = true ) - val table = Table(("x", "y"), cases:_*) - forAll(table) { (x, expectedRes) => - val res = f.checkEquality(x) - val resValue = res.map(_._1) - if (activatedVersionInTests >= VersionContext.JitActivationVersion) { - val expected = expectedRes.newResults(ergoTreeVersionInTests)._1 - checkResult(resValue, expected.value, failOnTestVectors = true) - if (res.isSuccess) { - res.get._2.cost shouldBe JitCost(expected.verificationCost.get) - } - } - } + testCases(cases, f) } val f = existingFeature( @@ -6067,26 +7398,51 @@ class SigmaDslSpecification extends SigmaDslTesting e.getTargetException.getMessage.contains("Unsupported lambda in flatMap") } ) - } + } + + property("Coll patch method equivalence") { + val samples = genSamples(collWithRangeGen, MinSuccessful(50)) + def costDetails(i: Int) = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + SeqCostItem(MethodDesc(SCollection.PatchMethod), PerItemCost(JitCost(30), JitCost(2), 10), i) + ) + ) - property("Coll patch method equivalence") { - val samples = genSamples(collWithRangeGen, MinSuccessful(50)) verifyCases( { - def success[T](v: T) = Expected(Success(v), 37514) + def success[T](v: T, cd: CostDetails) = Expected(Success(v), 37514, cd, 1796) Seq( - ((Coll[Int](), (0, 0)), success(Coll[Int]())), - ((Coll[Int](1), (0, 0)), success(Coll[Int](1, 1))), - ((Coll[Int](1), (0, 1)), success(Coll[Int](1))), - ((Coll[Int](1, 2), (0, 0)), success(Coll[Int](1, 2, 1, 2))), - ((Coll[Int](1, 2), (1, 0)), success(Coll[Int](1, 1, 2, 2))), - ((Coll[Int](1, 2), (0, 2)), success(Coll[Int](1, 2))), - ((Coll[Int](1, 2), (0, 3)), success(Coll[Int](1, 2))), - ((Coll[Int](1, 2), (1, 2)), success(Coll[Int](1, 1, 2))), - ((Coll[Int](1, 2), (2, 0)), success(Coll[Int](1, 2, 1, 2))), - ((Coll[Int](1, 2), (3, 0)), success(Coll[Int](1, 2, 1, 2))), - ((Coll[Int](1, 2), (3, 1)), success(Coll[Int](1, 2, 1, 2))), - ((Coll[Int](1, 2), (-1, 1)), success(Coll[Int](1, 2, 2))) + ((Coll[Int](), (0, 0)), success(Coll[Int](), costDetails(0))), + ((Coll[Int](1), (0, 0)), success(Coll[Int](1, 1), costDetails(2))), + ((Coll[Int](1), (0, 1)), success(Coll[Int](1), costDetails(2))), + ((Coll[Int](1, 2), (0, 0)), success(Coll[Int](1, 2, 1, 2), costDetails(4))), + ((Coll[Int](1, 2), (1, 0)), success(Coll[Int](1, 1, 2, 2), costDetails(4))), + ((Coll[Int](1, 2), (0, 2)), success(Coll[Int](1, 2), costDetails(4))), + ((Coll[Int](1, 2), (0, 3)), success(Coll[Int](1, 2), costDetails(4))), + ((Coll[Int](1, 2), (1, 2)), success(Coll[Int](1, 1, 2), costDetails(4))), + ((Coll[Int](1, 2), (2, 0)), success(Coll[Int](1, 2, 1, 2), costDetails(4))), + ((Coll[Int](1, 2), (3, 0)), success(Coll[Int](1, 2, 1, 2), costDetails(4))), + ((Coll[Int](1, 2), (3, 1)), success(Coll[Int](1, 2, 1, 2), costDetails(4))), + ((Coll[Int](1, 2), (-1, 1)), success(Coll[Int](1, 2, 2), costDetails(4))) ) }, existingFeature( @@ -6138,16 +7494,37 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Coll updated method equivalence") { + def costDetails(i: Int) = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + SeqCostItem(MethodDesc(SCollection.UpdatedMethod), PerItemCost(JitCost(20), JitCost(1), 10), i) + ) + ) verifyCases( // (coll, (index, elem)) { - def success[T](v: T) = Expected(Success(v), 37180) + def success[T](v: T, cd: CostDetails) = Expected(Success(v), 37180, cd, 1794) Seq( ((Coll[Int](), (0, 0)), Expected(new IndexOutOfBoundsException("0"))), - ((Coll[Int](1), (0, 0)), success(Coll[Int](0))), - ((Coll[Int](1, 2), (0, 0)), success(Coll[Int](0, 2))), - ((Coll[Int](1, 2), (1, 0)), success(Coll[Int](1, 0))), - ((Coll[Int](1, 2, 3), (2, 0)), success(Coll[Int](1, 2, 0))), + ((Coll[Int](1), (0, 0)), success(Coll[Int](0), costDetails(1))), + ((Coll[Int](1, 2), (0, 0)), success(Coll[Int](0, 2), costDetails(2))), + ((Coll[Int](1, 2), (1, 0)), success(Coll[Int](1, 0), costDetails(2))), + ((Coll[Int](1, 2, 3), (2, 0)), success(Coll[Int](1, 2, 0), costDetails(3))), ((Coll[Int](1, 2), (2, 0)), Expected(new IndexOutOfBoundsException("2"))), ((Coll[Int](1, 2), (3, 0)), Expected(new IndexOutOfBoundsException("3"))), ((Coll[Int](1, 2), (-1, 0)), Expected(new IndexOutOfBoundsException("-1"))) @@ -6194,27 +7571,48 @@ class SigmaDslSpecification extends SigmaDslTesting } yield (coll, (is.toColl, vs)), MinSuccessful(20)) + def costDetails(i: Int) = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + SeqCostItem(MethodDesc(SCollection.UpdateManyMethod), PerItemCost(JitCost(20), JitCost(2), 10), i) + ) + ) verifyCases( // (coll, (indexes, values)) { - def success[T](v: T) = Expected(Success(v), 37817) + def success[T](v: T, i: Int) = Expected(Success(v), 37817, costDetails(i), 1794) Seq( ((Coll[Int](), (Coll(0), Coll(0))), Expected(new IndexOutOfBoundsException("0"))), ((Coll[Int](), (Coll(0, 1), Coll(0, 0))), Expected(new IndexOutOfBoundsException("0"))), ((Coll[Int](), (Coll(0, 1), Coll(0))), Expected(new IllegalArgumentException("requirement failed: Collections should have same length but was 2 and 1:\n xs=Coll(0,1);\n ys=Coll(0)"))), - ((Coll[Int](1), (Coll(0), Coll(0))), success(Coll[Int](0))), + ((Coll[Int](1), (Coll(0), Coll(0))), success(Coll[Int](0), 1)), ((Coll[Int](1), (Coll(0, 1), Coll(0, 0))), Expected(new IndexOutOfBoundsException("1"))), - ((Coll[Int](1, 2), (Coll(0), Coll(0))), success(Coll[Int](0, 2))), - ((Coll[Int](1, 2), (Coll(0, 1), Coll(0, 0))), success(Coll[Int](0, 0))), + ((Coll[Int](1, 2), (Coll(0), Coll(0))), success(Coll[Int](0, 2), 2)), + ((Coll[Int](1, 2), (Coll(0, 1), Coll(0, 0))), success(Coll[Int](0, 0), 2)), ((Coll[Int](1, 2), (Coll(0, 1, 2), Coll(0, 0, 0))), Expected(new IndexOutOfBoundsException("2"))), - ((Coll[Int](1, 2), (Coll(1), Coll(0))), success(Coll[Int](1, 0))), - ((Coll[Int](1, 2, 3), (Coll(2), Coll(0))), success(Coll[Int](1, 2, 0))), + ((Coll[Int](1, 2), (Coll(1), Coll(0))), success(Coll[Int](1, 0), 2)), + ((Coll[Int](1, 2, 3), (Coll(2), Coll(0))), success(Coll[Int](1, 2, 0), 3)), ((Coll[Int](1, 2), (Coll(2), Coll(0))), Expected(new IndexOutOfBoundsException("2"))), ((Coll[Int](1, 2), (Coll(3), Coll(0))), Expected(new IndexOutOfBoundsException("3"))), ((Coll[Int](1, 2), (Coll(-1), Coll(0))), Expected(new IndexOutOfBoundsException("-1"))), ((Coll[Int](10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140), (Coll[Int](12, 12, 4, 11, 1, 8, 0, 1), Coll[Int](-10, -20, -30, -40, -50, -60, -70, -80))), - success(Coll[Int](-70, -80, 30, 40, -30, 60, 70, 80, -60, 100, 110, -40, -20, 140))) + success(Coll[Int](-70, -80, 30, 40, -30, 60, 70, 80, -60, 100, 110, -40, -20, 140), 14)) ) }, existingFeature( @@ -6291,21 +7689,98 @@ class SigmaDslSpecification extends SigmaDslTesting property("Coll fold method equivalence") { val n = ExactNumeric.IntIsExactNumeric - def success[T](v: T, c: Int) = Expected(Success(v), c) + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + TypeBasedCostItem(ArithOp.Plus, SInt) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 2), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + TypeBasedCostItem(ArithOp.Plus, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + TypeBasedCostItem(ArithOp.Plus, SInt) + ) + ) + val costDetails4 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 3), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + TypeBasedCostItem(ArithOp.Plus, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + TypeBasedCostItem(ArithOp.Plus, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + TypeBasedCostItem(ArithOp.Plus, SInt) + ) + ) if (lowerMethodCallsInTests) { verifyCases( // (coll, initState) { Seq( - ((Coll[Byte](), 0), success(0, 41266)), - ((Coll[Byte](), Int.MaxValue), success(Int.MaxValue, 41266)), - ((Coll[Byte](1), Int.MaxValue - 1), success(Int.MaxValue, 41396)), + ((Coll[Byte](), 0), Expected(Success(0), 41266, costDetails1, 1787)), + ((Coll[Byte](), Int.MaxValue), Expected(Success(Int.MaxValue), 41266, costDetails1, 1787)), + ((Coll[Byte](1), Int.MaxValue - 1), Expected(Success(Int.MaxValue), 41396, costDetails2, 1793)), ((Coll[Byte](1), Int.MaxValue), Expected(new ArithmeticException("integer overflow"))), - ((Coll[Byte](-1), Int.MinValue + 1), success(Int.MinValue, 41396)), + ((Coll[Byte](-1), Int.MinValue + 1), Expected(Success(Int.MinValue), 41396, costDetails2, 1793)), ((Coll[Byte](-1), Int.MinValue), Expected(new ArithmeticException("integer overflow"))), - ((Coll[Byte](1, 2), 0), success(3, 41526)), - ((Coll[Byte](1, -1), 0), success(0, 41526)), - ((Coll[Byte](1, -1, 1), 0), success(1, 41656)) + ((Coll[Byte](1, 2), 0), Expected(Success(3), 41526, costDetails3, 1799)), + ((Coll[Byte](1, -1), 0), Expected(Success(0), 41526, costDetails3, 1799)), + ((Coll[Byte](1, -1, 1), 0), Expected(Success(1), 41656, costDetails4, 1805)) ) }, existingFeature( @@ -6329,7 +7804,7 @@ class SigmaDslSpecification extends SigmaDslTesting } else { assertExceptionThrown( verifyCases( - Seq( ((Coll[Byte](), 0), success(0, 41266)) ), + Seq( ((Coll[Byte](), 0), Expected(Success(0), 41266)) ), existingFeature( { (x: (Coll[Byte], Int)) => x._1.foldLeft(x._2, { i: (Int, Byte) => n.plus(i._1, i._2) }) }, "{ (x: (Coll[Byte], Int)) => x._1.fold(x._2, { (i1: Int, i2: Byte) => i1 + i2 }) }" @@ -6341,21 +7816,213 @@ class SigmaDslSpecification extends SigmaDslTesting property("Coll fold with nested If") { val n = ExactNumeric.IntIsExactNumeric - def success[T](v: T, c: Int) = Expected(Success(v), c) + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Plus, SInt) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse) + ) + ) + val costDetails4 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 2), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Plus, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Plus, SInt) + ), + Some(232417L) + ) + val costDetails5 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 2), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Plus, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse) + ) + ) + val costDetails6 = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Fold), PerItemCost(JitCost(3), JitCost(1), 10), 3), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Plus, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 2), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + TypeBasedCostItem(Upcast, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Plus, SInt) + ) + ) if (lowerMethodCallsInTests) { verifyCases( // (coll, initState) { Seq( - ((Coll[Byte](), 0), success(0, 42037)), - ((Coll[Byte](), Int.MaxValue), success(Int.MaxValue, 42037)), - ((Coll[Byte](1), Int.MaxValue - 1), success(Int.MaxValue, 42197)), + ((Coll[Byte](), 0), Expected(Success(0), 42037, costDetails1, 1787)), + ((Coll[Byte](), Int.MaxValue), Expected(Success(Int.MaxValue), 42037, costDetails1, 1787)), + ((Coll[Byte](1), Int.MaxValue - 1), Expected(Success(Int.MaxValue), 42197, costDetails2, 1799)), ((Coll[Byte](1), Int.MaxValue), Expected(new ArithmeticException("integer overflow"))), - ((Coll[Byte](-1), Int.MinValue + 1), success(Int.MinValue + 1, 42197)), - ((Coll[Byte](-1), Int.MinValue), success(Int.MinValue, 42197)), - ((Coll[Byte](1, 2), 0), success(3, 42357)), - ((Coll[Byte](1, -1), 0), success(1, 42357)), - ((Coll[Byte](1, -1, 1), 0), success(2, 42517)) + ((Coll[Byte](-1), Int.MinValue + 1), Expected(Success(Int.MinValue + 1), 42197, costDetails3, 1797)), + ((Coll[Byte](-1), Int.MinValue), Expected(Success(Int.MinValue), 42197, costDetails3, 1797)), + ((Coll[Byte](1, 2), 0), Expected(Success(3), 42357, costDetails4, 1811)), + ((Coll[Byte](1, -1), 0), Expected(Success(1), 42357, costDetails5, 1809)), + ((Coll[Byte](1, -1, 1), 0), Expected(Success(2), 42517, costDetails6, 1821)) ) }, existingFeature( @@ -6396,7 +8063,7 @@ class SigmaDslSpecification extends SigmaDslTesting } else { assertExceptionThrown( verifyCases( - Seq( ((Coll[Byte](), 0), success(0, 42037)) ), + Seq( ((Coll[Byte](), 0), Expected(Success(0), 42037)) ), existingFeature( { (x: (Coll[Byte], Int)) => x._1.foldLeft(x._2, { i: (Int, Byte) => if (i._2 > 0) n.plus(i._1, i._2) else i._1 }) }, "{ (x: (Coll[Byte], Int)) => x._1.fold(x._2, { (i1: Int, i2: Byte) => if (i2 > 0) i1 + i2 else i1 }) }" @@ -6407,29 +8074,55 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Coll indexOf method equivalence") { + def costDetails(i: Int) = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField) + ) + ++ Array.fill(i)(FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3)))) + :+ SeqCostItem(MethodDesc(SCollection.IndexOfMethod), PerItemCost(JitCost(20), JitCost(10), 2), i) + ) verifyCases( // (coll, (elem: Byte, from: Int)) { - def success[T](v: T) = Expected(Success(v), 37649) + def success0[T](v: T) = Expected(Success(v), 37649, costDetails(0), 1793) + def success1[T](v: T) = Expected(Success(v), 37649, costDetails(1), 1793) + def success2[T](v: T) = Expected(Success(v), 37649, costDetails(2), 1794) + def success3[T](v: T) = Expected(Success(v), 37649, costDetails(3), 1795) + def success12[T](v: T) = Expected(Success(v), 37649, costDetails(12), 1802) Seq( - ((Coll[Byte](), (0.toByte, 0)), success(-1)), - ((Coll[Byte](), (0.toByte, -1)), success(-1)), - ((Coll[Byte](), (0.toByte, 1)), success(-1)), - ((Coll[Byte](1), (0.toByte, 0)), success(-1)), - ((Coll[Byte](1), (1.toByte, 0)), success(0)), - ((Coll[Byte](1), (1.toByte, 1)), success(-1)), - ((Coll[Byte](1, 1), (0.toByte, -1)), success(-1)), - ((Coll[Byte](1, 1), (0.toByte, 0)), success(-1)), - ((Coll[Byte](1, 1), (1.toByte, -1)), success(0)), - ((Coll[Byte](1, 1), (1.toByte, 0)), success(0)), - ((Coll[Byte](1, 1), (1.toByte, 1)), success(1)), - ((Coll[Byte](1, 1), (1.toByte, 2)), success(-1)), - ((Coll[Byte](1, 1), (1.toByte, 3)), success(-1)), - ((Coll[Byte](1, 2, 3), (3.toByte, 0)), success(2)), - ((Coll[Byte](1, 2, 3), (3.toByte, 1)), success(2)), - ((Coll[Byte](1, 2, 3), (3.toByte, 2)), success(2)), - ((Coll[Byte](1, 2, 3), (3.toByte, 3)), success(-1)), - ((Helpers.decodeBytes("8085623fb7cd6b7f01801f00800100"), (0.toByte, -1)), success(11)) + ((Coll[Byte](), (0.toByte, 0)), success0(-1)), + ((Coll[Byte](), (0.toByte, -1)), success0(-1)), + ((Coll[Byte](), (0.toByte, 1)), success0(-1)), + ((Coll[Byte](1), (0.toByte, 0)), success1(-1)), + ((Coll[Byte](1), (1.toByte, 0)), success1(0)), + ((Coll[Byte](1), (1.toByte, 1)), success0(-1)), + ((Coll[Byte](1, 1), (0.toByte, -1)), success2(-1)), + ((Coll[Byte](1, 1), (0.toByte, 0)), success2(-1)), + ((Coll[Byte](1, 1), (1.toByte, -1)), success1(0)), + ((Coll[Byte](1, 1), (1.toByte, 0)), success1(0)), + ((Coll[Byte](1, 1), (1.toByte, 1)), success1(1)), + ((Coll[Byte](1, 1), (1.toByte, 2)), success0(-1)), + ((Coll[Byte](1, 1), (1.toByte, 3)), success0(-1)), + ((Coll[Byte](1, 2, 3), (3.toByte, 0)), success3(2)), + ((Coll[Byte](1, 2, 3), (3.toByte, 1)), success2(2)), + ((Coll[Byte](1, 2, 3), (3.toByte, 2)), success1(2)), + ((Coll[Byte](1, 2, 3), (3.toByte, 3)), success0(-1)), + ((Helpers.decodeBytes("8085623fb7cd6b7f01801f00800100"), (0.toByte, -1)), success12(11)) ) }, existingFeature( @@ -6462,9 +8155,17 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Coll apply method equivalence") { + val costDetails = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ByIndex) + ) + ) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36410) + def success[T](v: T) = Expected(Success(v), 36410, costDetails, 1789) Seq( ((Coll[Int](), 0), Expected(new ArrayIndexOutOfBoundsException("0"))), ((Coll[Int](), -1), Expected(new ArrayIndexOutOfBoundsException("-1"))), @@ -6493,11 +8194,31 @@ class SigmaDslSpecification extends SigmaDslTesting property("Coll getOrElse method equivalence") { val default = 10 + val costDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ByIndex) + ) + ) if (lowerMethodCallsInTests) { verifyCases( // (coll, (index, default)) { - def success[T](v: T) = Expected(Success(v), 37020) + def success[T](v: T) = Expected(Success(v), 37020, costDetails, 1793) Seq( ((Coll[Int](), (0, default)), success(default)), ((Coll[Int](), (-1, default)), success(default)), @@ -6549,11 +8270,28 @@ class SigmaDslSpecification extends SigmaDslTesting newVersionedResults = { // in v5.0 MethodCall ErgoTree node is allowed val res = ExpectedResult( Success(1), Some(166) ) - Seq( // expected result for each version - 0 -> ( res -> None ), - 1 -> ( res -> None ), - 2 -> ( res -> None ) + val details = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(MethodCall), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(SCollection.GetOrElseMethod, FixedCost(JitCost(30))) + ) ) + Seq.tabulate(3)(v => v -> ( res -> Some(details) )) // expected result for each version } ) ) @@ -6600,9 +8338,19 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Tuple size method equivalence") { + val costDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(Constant) + ) + ) verifyCases( { - def success[T](v: T) = Expected(Success(v), 35905) + def success[T](v: T) = Expected(Success(v), 35905, costDetails, 1783) Seq( ((0, 0), success(2)), ((1, 2), success(2)) @@ -6615,8 +8363,9 @@ class SigmaDslSpecification extends SigmaDslTesting property("Tuple apply method equivalence") { val samples = genSamples[(Int, Int)](DefaultMinSuccessful) + val costDetails = TracedCost(traceBase :+ FixedCostItem(SelectField)) verifyCases( - Seq(((1, 2), Expected(Success(1), cost = 36013))), + Seq(((1, 2), Expected(Success(1), cost = 36013, costDetails, 1784))), existingFeature((x: (Int, Int)) => x._1, "{ (x: (Int, Int)) => x(0) }", FuncValue( @@ -6625,7 +8374,7 @@ class SigmaDslSpecification extends SigmaDslTesting )), preGeneratedSamples = Some(samples)) verifyCases( - Seq(((1, 2), Expected(Success(2), cost = 36013))), + Seq(((1, 2), Expected(Success(2), cost = 36013, costDetails, 1784))), existingFeature((x: (Int, Int)) => x._2, "{ (x: (Int, Int)) => x(1) }", FuncValue( @@ -6636,14 +8385,31 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Coll map method equivalence") { + def repeatPlusChunk(i: Int): Array[CostItem] = Array.fill(i){ + Array( + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(ArithOp.Plus, SInt) + ) + }.flatten + def costDetails(i: Int) = TracedCost( + traceBase + ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(MapCollection), PerItemCost(JitCost(20), JitCost(1), 10), i) + ) + ++ repeatPlusChunk(i) + ) + val n = ExactNumeric.IntIsExactNumeric verifyCases( { def success[T](v: T, c: Int) = Expected(Success(v), c) Seq( - (Coll[Int](), success(Coll[Int](), 38886)), - (Coll[Int](1), success(Coll[Int](2), 38936)), - (Coll[Int](1, 2), success(Coll[Int](2, 3), 38986)), + (Coll[Int](), Expected(Success(Coll[Int]()), 38886, costDetails(0), 1788)), + (Coll[Int](1), Expected(Success(Coll[Int](2)), 38936, costDetails(1), 1791)), + (Coll[Int](1, 2), Expected(Success(Coll[Int](2, 3)), 38986, costDetails(2), 1794)), (Coll[Int](1, 2, Int.MaxValue), Expected(new ArithmeticException("integer overflow"))) ) }, @@ -6659,15 +8425,71 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Coll map with nested if") { + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(MapCollection), PerItemCost(JitCost(20), JitCost(1), 10), 0) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(MapCollection), PerItemCost(JitCost(20), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(ArithOp.Plus, SInt) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(MapCollection), PerItemCost(JitCost(20), JitCost(1), 10), 1), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(Constant), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Multiply, SInt) + ) + ) + val costDetails4 = TracedCost( + traceBase ++ Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(MapCollection), PerItemCost(JitCost(20), JitCost(1), 10), 2), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(ArithOp.Plus, SInt), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(Constant), + FixedCostItem(ValUse), + TypeBasedCostItem(ArithOp.Multiply, SInt) + ) + ) val n = ExactNumeric.IntIsExactNumeric verifyCases( { def success[T](v: T, c: Int) = Expected(Success(v), c) Seq( - (Coll[Int](), success(Coll[Int](), 39571)), - (Coll[Int](1), success(Coll[Int](2), 39671)), - (Coll[Int](-1), success(Coll[Int](1), 39671)), - (Coll[Int](1, -2), success(Coll[Int](2, 2), 39771)), + (Coll[Int](), Expected(Success(Coll[Int]()), 39571, costDetails1, 1788)), + (Coll[Int](1), Expected(Success(Coll[Int](2)), 39671, costDetails2, 1795)), + (Coll[Int](-1), Expected(Success(Coll[Int](1)), 39671, costDetails3, 1795)), + (Coll[Int](1, -2), Expected(Success(Coll[Int](2, 2)), 39771, costDetails4, 1802)), (Coll[Int](1, 2, Int.MaxValue), Expected(new ArithmeticException("integer overflow"))), (Coll[Int](1, 2, Int.MinValue), Expected(new ArithmeticException("integer overflow"))) ) @@ -6692,16 +8514,35 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Coll filter") { + def costDetails(i: Int) = { + val gtChunk = Array.fill(i)( + Array( + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt) + ) + ).flatten + + TracedCost( + traceBase ++ + Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Filter), PerItemCost(JitCost(20), JitCost(1), 10), i) + ) ++ + gtChunk + ) + } + val o = ExactOrdering.IntIsExactOrdering verifyCases( { - def success[T](v: T, c: Int) = Expected(Success(v), c) Seq( - (Coll[Int](), success(Coll[Int](), 37223)), - (Coll[Int](1), success(Coll[Int](1), 37273)), - (Coll[Int](1, 2), success(Coll[Int](1, 2), 37323)), - (Coll[Int](1, 2, -1), success(Coll[Int](1, 2), 37373)), - (Coll[Int](1, -1, 2, -2), success(Coll[Int](1, 2), 37423)) + (Coll[Int](), Expected(Success(Coll[Int]()), 37223, costDetails(0), 1788)), + (Coll[Int](1), Expected(Success(Coll[Int](1)), 37273, costDetails(1), 1791)), + (Coll[Int](1, 2), Expected(Success(Coll[Int](1, 2)), 37323, costDetails(2), 1795)), + (Coll[Int](1, 2, -1), Expected(Success(Coll[Int](1, 2)), 37373, costDetails(3), 1798)), + (Coll[Int](1, -1, 2, -2), Expected(Success(Coll[Int](1, 2)), 37423, costDetails(4), 1802)) ) }, existingFeature((x: Coll[Int]) => x.filter({ (v: Int) => o.gt(v, 0) }), @@ -6716,17 +8557,69 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Coll filter with nested If") { + val leftBranch = Array( + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(LT, SInt) + ) + val rightBranch = Array( + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SInt), + FixedCostItem(If), + FixedCostItem(Constant) + ) + def repeatLeftBranch(i: Int) = Array.fill(i)(leftBranch).flatten + + def costDetails(i: Int) = { + TracedCost( + traceBase ++ + Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Filter), PerItemCost(JitCost(20), JitCost(1), 10), i) + ) ++ + repeatLeftBranch(i) + ) + } + val costDetails3 = TracedCost( + traceBase ++ + Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Filter), PerItemCost(JitCost(20), JitCost(1), 10), 3) + ) ++ + repeatLeftBranch(2) ++ + rightBranch + ) + val costDetails5 = TracedCost( + traceBase ++ + Array( + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(Filter), PerItemCost(JitCost(20), JitCost(1), 10), 5) + ) ++ + leftBranch ++ + rightBranch ++ + leftBranch ++ + rightBranch ++ + leftBranch + ) + val o = ExactOrdering.IntIsExactOrdering verifyCases( { def success[T](v: T, c: Int) = Expected(Success(v), c) Seq( - (Coll[Int](), success(Coll[Int](), 37797)), - (Coll[Int](1), success(Coll[Int](1), 37887)), - (Coll[Int](10), success(Coll[Int](), 37887)), - (Coll[Int](1, 2), success(Coll[Int](1, 2), 37977)), - (Coll[Int](1, 2, 0), success(Coll[Int](1, 2), 38067)), - (Coll[Int](1, -1, 2, -2, 11), success(Coll[Int](1, 2), 38247)) + (Coll[Int](), Expected(Success(Coll[Int]()), 37797, costDetails(0), 1788)), + (Coll[Int](1), Expected(Success(Coll[Int](1)), 37887, costDetails(1), 1795)), + (Coll[Int](10), Expected(Success(Coll[Int]()), 37887, costDetails(1), 1795)), + (Coll[Int](1, 2), Expected(Success(Coll[Int](1, 2)), 37977, costDetails(2), 1803)), + (Coll[Int](1, 2, 0), Expected(Success(Coll[Int](1, 2)), 38067, costDetails3, 1808)), + (Coll[Int](1, -1, 2, -2, 11), Expected(Success(Coll[Int](1, 2)), 38247, costDetails5, 1820)) ) }, existingFeature((x: Coll[Int]) => x.filter({ (v: Int) => if (o.gt(v, 0)) v < 10 else false }), @@ -6744,23 +8637,44 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Coll slice method equivalence") { + def costDetails(i: Int) = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + SeqCostItem(CompanionDesc(Slice), PerItemCost(JitCost(10), JitCost(2), 100), i) + ) + ) val samples = genSamples(collWithRangeGen, DefaultMinSuccessful) if (lowerMethodCallsInTests) { verifyCases( - // (coll, (from, until)) { - def success[T](v: T) = Expected(Success(v), 36964) + val cost = 36964 + val newCost = 1792 Seq( - ((Coll[Int](), (-1, 0)), success(Coll[Int]())), - ((Coll[Int](), (0, 0)), success(Coll[Int]())), - ((Coll[Int](1), (0, 0)), success(Coll[Int]())), - ((Coll[Int](1), (0, -1)), success(Coll[Int]())), - ((Coll[Int](1), (1, 1)), success(Coll[Int]())), - ((Coll[Int](1), (-1, 1)), success(Coll[Int](1))), - ((Coll[Int](1, 2), (1, 1)), success(Coll[Int]())), - ((Coll[Int](1, 2), (1, 0)), success(Coll[Int]())), - ((Coll[Int](1, 2), (1, 2)), success(Coll[Int](2))), - ((Coll[Int](1, 2, 3, 4), (1, 3)), success(Coll[Int](2, 3))) + // (coll, (from, until)) + ((Coll[Int](), (-1, 0)), Expected(Success(Coll[Int]()), cost, costDetails(1), newCost)), + ((Coll[Int](), (0, 0)), Expected(Success(Coll[Int]()), cost, costDetails(0), newCost)), + ((Coll[Int](1), (0, 0)), Expected(Success(Coll[Int]()), cost, costDetails(0), newCost)), + ((Coll[Int](1), (0, -1)), Expected(Success(Coll[Int]()), cost, costDetails(0), newCost)), + ((Coll[Int](1), (1, 1)), Expected(Success(Coll[Int]()), cost, costDetails(0), newCost)), + ((Coll[Int](1), (-1, 1)), Expected(Success(Coll[Int](1)), cost, costDetails(2), newCost)), + ((Coll[Int](1, 2), (1, 1)), Expected(Success(Coll[Int]()), cost, costDetails(0), newCost)), + ((Coll[Int](1, 2), (1, 0)), Expected(Success(Coll[Int]()), cost, costDetails(0), newCost)), + ((Coll[Int](1, 2), (1, 2)), Expected(Success(Coll[Int](2)), cost, costDetails(1), newCost)), + ((Coll[Int](1, 2, 3, 4), (1, 3)), Expected(Success(Coll[Int](2, 3)), cost, costDetails(2), newCost)) ) }, existingFeature((x: (Coll[Int], (Int, Int))) => x._1.slice(x._2._1, x._2._2), @@ -6792,7 +8706,7 @@ class SigmaDslSpecification extends SigmaDslTesting } else { assertExceptionThrown( verifyCases( - Seq( (Coll[Int](), (-1, 0)) -> Expected(Success(Coll[Int]()), 37765) ), + Seq( (Coll[Int](), (-1, 0)) -> Expected(Success(Coll[Int]()), 0, CostDetails.ZeroCost, 0) ), existingFeature((x: (Coll[Int], (Int, Int))) => x._1.slice(x._2._1, x._2._2), "{ (x: (Coll[Int], (Int, Int))) => x._1.slice(x._2._1, x._2._2) }" )), @@ -6802,21 +8716,29 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Coll.append equivalence") { + def costDetails(i: Int) = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + SeqCostItem(CompanionDesc(Append), PerItemCost(JitCost(20), JitCost(2), 100), i) + ) + ) if (lowerMethodCallsInTests) { verifyCases( { - def success[T](v: T) = Expected(Success(v), 37765) + def success[T](v: T, size: Int) = Expected(Success(v), 37765, costDetails(size), 1790) val arr1 = Gen.listOfN(100, arbitrary[Int]).map(_.toArray).sample.get val arr2 = Gen.listOfN(200, arbitrary[Int]).map(_.toArray).sample.get Seq( - (Coll[Int](), Coll[Int]()) -> success(Coll[Int]()), - (Coll[Int](), Coll[Int](1)) -> success(Coll[Int](1)), - (Coll[Int](1), Coll[Int]()) -> success(Coll[Int](1)), - (Coll[Int](1), Coll[Int](2)) -> success(Coll[Int](1, 2)), - (Coll[Int](1), Coll[Int](2, 3)) -> success(Coll[Int](1, 2, 3)), - (Coll[Int](1, 2), Coll[Int](3)) -> success(Coll[Int](1, 2, 3)), - (Coll[Int](1, 2), Coll[Int](3, 4)) -> success(Coll[Int](1, 2, 3, 4)), - (Coll[Int](arr1:_*), Coll[Int](arr2:_*)) -> Expected(Success(Coll[Int](arr1 ++ arr2:_*)), 37785) + (Coll[Int](), Coll[Int]()) -> success(Coll[Int](), 0), + (Coll[Int](), Coll[Int](1)) -> success(Coll[Int](1), 1), + (Coll[Int](1), Coll[Int]()) -> success(Coll[Int](1), 1), + (Coll[Int](1), Coll[Int](2)) -> success(Coll[Int](1, 2), 2), + (Coll[Int](1), Coll[Int](2, 3)) -> success(Coll[Int](1, 2, 3), 3), + (Coll[Int](1, 2), Coll[Int](3)) -> success(Coll[Int](1, 2, 3), 3), + (Coll[Int](1, 2), Coll[Int](3, 4)) -> success(Coll[Int](1, 2, 3, 4), 4), + (Coll[Int](arr1:_*), Coll[Int](arr2:_*)) -> Expected(Success(Coll[Int](arr1 ++ arr2:_*)), 37785, costDetails(300), 1791) ) }, existingFeature( @@ -6849,37 +8771,80 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Option methods equivalence") { - def success[T](v: T, c: Int) = Expected(Success(v), c) + val costDetails1 = TracedCost(traceBase :+ FixedCostItem(OptionGet)) + val costDetails2 = TracedCost(traceBase :+ FixedCostItem(OptionIsDefined)) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(Constant), + FixedCostItem(OptionGetOrElse) + ) + ) + val costDetails4 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.FilterMethod, FixedCost(JitCost(20))) + ) + ) + val costDetails5 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.FilterMethod, FixedCost(JitCost(20))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + FixedCostItem(NamedDesc("EQ_Prim"), FixedCost(JitCost(3))) + ) + ) + val costDetails6 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.MapMethod, FixedCost(JitCost(20))) + ) + ) + val costDetails7 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.MapMethod, FixedCost(JitCost(20))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(ArithOp.Plus, SLong) + ) + ) verifyCases( Seq( (None -> Expected(new NoSuchElementException("None.get"))), - (Some(10L) -> success(10L, 36046))), + (Some(10L) -> Expected(Success(10L), 36046, costDetails1, 1785))), existingFeature({ (x: Option[Long]) => x.get }, "{ (x: Option[Long]) => x.get }", FuncValue(Vector((1, SOption(SLong))), OptionGet(ValUse(1, SOption(SLong)))))) verifyCases( Seq( - (None -> success(false, 36151)), - (Some(10L) -> success(true, 36151))), + (None -> Expected(Success(false), 36151, costDetails2, 1784)), + (Some(10L) -> Expected(Success(true), 36151, costDetails2, 1784))), existingFeature({ (x: Option[Long]) => x.isDefined }, "{ (x: Option[Long]) => x.isDefined }", FuncValue(Vector((1, SOption(SLong))), OptionIsDefined(ValUse(1, SOption(SLong)))))) verifyCases( Seq( - (None -> success(1L, 36367)), - (Some(10L) -> success(10L, 36367))), + (None -> Expected(Success(1L), 36367, costDetails3, 1786)), + (Some(10L) -> Expected(Success(10L), 36367, costDetails3, 1786))), existingFeature({ (x: Option[Long]) => x.getOrElse(1L) }, "{ (x: Option[Long]) => x.getOrElse(1L) }", FuncValue(Vector((1, SOption(SLong))), OptionGetOrElse(ValUse(1, SOption(SLong)), LongConstant(1L))))) verifyCases( Seq( - (None -> success(None, 38239)), - (Some(10L) -> success(None, 38239)), - (Some(1L) -> success(Some(1L), 38239))), + (None -> Expected(Success(None), 38239, costDetails4, 1786)), + (Some(10L) -> Expected(Success(None), 38239, costDetails5, 1788)), + (Some(1L) -> Expected(Success(Some(1L)), 38239, costDetails5, 1789))), existingFeature({ (x: Option[Long]) => x.filter({ (v: Long) => v == 1} ) }, "{ (x: Option[Long]) => x.filter({ (v: Long) => v == 1 }) }", FuncValue( @@ -6895,8 +8860,8 @@ class SigmaDslSpecification extends SigmaDslTesting val n = ExactNumeric.LongIsExactNumeric verifyCases( Seq( - (None -> success(None, 38575)), - (Some(10L) -> success(Some(11L), 38575)), + (None -> Expected(Success(None), 38575, costDetails6, 1786)), + (Some(10L) -> Expected(Success(Some(11L)), 38575, costDetails7, 1790)), (Some(Long.MaxValue) -> Expected(new ArithmeticException("long overflow")))), existingFeature({ (x: Option[Long]) => x.map( (v: Long) => n.plus(v, 1) ) }, "{ (x: Option[Long]) => x.map({ (v: Long) => v + 1 }) }", @@ -6919,15 +8884,49 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Option filter,map with nested If") { - def success[T](v: T, c: Int) = Expected(Success(v), c) + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.FilterMethod, FixedCost(JitCost(20))) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.FilterMethod, FixedCost(JitCost(20))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) + val costDetails3 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.FilterMethod, FixedCost(JitCost(20))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(GT, SLong), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(LE, SLong) + ) + ) val o = ExactOrdering.LongIsExactOrdering verifyCases( Seq( - (None -> success(None, 38736)), - (Some(0L) -> success(None, 38736)), - (Some(10L) -> success(Some(10L), 38736)), - (Some(11L) -> success(None, 38736))), + (None -> Expected(Success(None), 38736, costDetails1, 1786)), + (Some(0L) -> Expected(Success(None), 38736, costDetails2, 1791)), + (Some(10L) -> Expected(Success(Some(10L)), 38736, costDetails3, 1794)), + (Some(11L) -> Expected(Success(None), 38736, costDetails3, 1794))), existingFeature( { (x: Option[Long]) => x.filter({ (v: Long) => if (o.gt(v, 0L)) v <= 10 else false } ) }, "{ (x: Option[Long]) => x.filter({ (v: Long) => if (v > 0) v <= 10 else false }) }", @@ -6950,13 +8949,48 @@ class SigmaDslSpecification extends SigmaDslTesting ) ))) + val costDetails4 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.MapMethod, FixedCost(JitCost(20))) + ) + ) + val costDetails5 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.MapMethod, FixedCost(JitCost(20))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(LT, SLong), + FixedCostItem(If), + FixedCostItem(ValUse) + ) + ) + val costDetails6 = TracedCost( + traceBase ++ Array( + FixedCostItem(MethodCall), + FixedCostItem(FuncValue), + FixedCostItem(SOption.MapMethod, FixedCost(JitCost(20))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(LT, SLong), + FixedCostItem(If), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(ArithOp.Minus, SLong) + ) + ) val n = ExactNumeric.LongIsExactNumeric verifyCases( Seq( - (None -> success(None, 39077)), - (Some(0L) -> success(Some(0L), 39077)), - (Some(10L) -> success(Some(10L), 39077)), - (Some(-1L) -> success(Some(-2L), 39077)), + (None -> Expected(Success(None), 39077, costDetails4, 1786)), + (Some(0L) -> Expected(Success(Some(0L)), 39077, costDetails5, 1792)), + (Some(10L) -> Expected(Success(Some(10L)), 39077, costDetails5, 1792)), + (Some(-1L) -> Expected(Success(Some(-2L)), 39077, costDetails6, 1794)), (Some(Long.MinValue) -> Expected(new ArithmeticException("long overflow")))), existingFeature( { (x: Option[Long]) => x.map( (v: Long) => if (o.lt(v, 0)) n.minus(v, 1) else v ) }, @@ -6998,20 +9032,41 @@ class SigmaDslSpecification extends SigmaDslTesting } property("Option fold workaround method") { + val costDetails1 = TracedCost( + traceBase ++ Array( + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + FixedCostItem(Constant) + ) + ) + val costDetails2 = TracedCost( + traceBase ++ Array( + FixedCostItem(OptionIsDefined), + FixedCostItem(If), + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(ValUse), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(Constant), + TypeBasedCostItem(ArithOp.Plus, SLong) + ) + ) val n = ExactNumeric.LongIsExactNumeric verifyCases( Seq( (None -> Expected( value = Failure(new NoSuchElementException("None.get")), cost = 0, - newDetails = CostDetails.ZeroCost, + expectedDetails = CostDetails.ZeroCost, newCost = 1786, - newVersionedResults = Seq( - 2 -> (ExpectedResult(Success(5L), Some(1786)) -> None) - ) + newVersionedResults = Seq.tabulate(3)(v => v -> (ExpectedResult(Success(5L), Some(1786)) -> Some(costDetails1))) )), - (Some(0L) -> Expected(Success(1L), cost = 39012, - expectedDetails = CostDetails.ZeroCost, + (Some(0L) -> Expected( + Success(1L), + cost = 39012, + expectedDetails = costDetails2, expectedNewCost = 1794)), (Some(Long.MaxValue) -> Expected(new ArithmeticException("long overflow"))) ), @@ -7070,22 +9125,29 @@ class SigmaDslSpecification extends SigmaDslTesting } property("blake2b256, sha256 equivalence") { - def success[T](v: T, c: Int) = Expected(Success(v), c) + def costDetailsBlake(i: Int) = TracedCost(traceBase :+ SeqCostItem(CompanionDesc(CalcBlake2b256), PerItemCost(JitCost(20), JitCost(7), 128), i)) + def costDetailsSha(i: Int) = TracedCost(traceBase :+ SeqCostItem(CompanionDesc(CalcSha256), PerItemCost(JitCost(80), JitCost(8), 64), i)) verifyCases( Seq( - Coll[Byte]() -> - success( - Helpers.decodeBytes("0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8"), - 36269), - Helpers.decodeBytes("e0ff0105ffffac31010017ff33") -> - success( - Helpers.decodeBytes("33707eed9aab64874ff2daa6d6a378f61e7da36398fb36c194c7562c9ff846b5"), - 36269), - Colls.replicate(1024, 1.toByte) -> - success( - Helpers.decodeBytes("45d8456fc5d41d1ec1124cb92e41192c1c3ec88f0bf7ae2dc6e9cf75bec22045"), - 36369) + Coll[Byte]() -> Expected( + Success(Helpers.decodeBytes("0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8")), + 36269, + costDetailsBlake(0), + 1788 + ), + Helpers.decodeBytes("e0ff0105ffffac31010017ff33") -> Expected( + Success(Helpers.decodeBytes("33707eed9aab64874ff2daa6d6a378f61e7da36398fb36c194c7562c9ff846b5")), + 36269, + costDetailsBlake(13), + 1788 + ), + Colls.replicate(1024, 1.toByte) -> Expected( + Success(Helpers.decodeBytes("45d8456fc5d41d1ec1124cb92e41192c1c3ec88f0bf7ae2dc6e9cf75bec22045")), + 36369, + costDetailsBlake(1024), + 1793 + ) ), existingFeature((x: Coll[Byte]) => SigmaDsl.blake2b256(x), "{ (x: Coll[Byte]) => blake2b256(x) }", @@ -7093,18 +9155,24 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( Seq( - Coll[Byte]() -> - success( - Helpers.decodeBytes("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), - 36393), - Helpers.decodeBytes("e0ff0105ffffac31010017ff33") -> - success( - Helpers.decodeBytes("367d0ec2cdc14aac29d5beb60c2bfc86d5a44a246308659af61c1b85fa2ca2cc"), - 36393), - Colls.replicate(1024, 1.toByte) -> - success( - Helpers.decodeBytes("5a648d8015900d89664e00e125df179636301a2d8fa191c1aa2bd9358ea53a69"), - 36493) + Coll[Byte]() -> Expected( + Success(Helpers.decodeBytes("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")), + 36393, + costDetailsSha(0), + 1794 + ), + Helpers.decodeBytes("e0ff0105ffffac31010017ff33") -> Expected( + Success(Helpers.decodeBytes("367d0ec2cdc14aac29d5beb60c2bfc86d5a44a246308659af61c1b85fa2ca2cc")), + 36393, + costDetailsSha(13), + 1794 + ), + Colls.replicate(1024, 1.toByte) -> Expected( + Success(Helpers.decodeBytes("5a648d8015900d89664e00e125df179636301a2d8fa191c1aa2bd9358ea53a69")), + 36493, + costDetailsSha(1024), + 1806 + ) ), existingFeature((x: Coll[Byte]) => SigmaDsl.sha256(x), "{ (x: Coll[Byte]) => sha256(x) }", @@ -7112,17 +9180,26 @@ class SigmaDslSpecification extends SigmaDslTesting } property("sigmaProp equivalence") { + val costDetails = TracedCost(traceBase :+ FixedCostItem(BoolToSigmaProp)) verifyCases( Seq( - (false, Expected(Success(CSigmaProp(TrivialProp.FalseProp)), 35892)), - (true, Expected(Success(CSigmaProp(TrivialProp.TrueProp)), 35892))), + (false, Expected(Success(CSigmaProp(TrivialProp.FalseProp)), 35892, costDetails, 1785)), + (true, Expected(Success(CSigmaProp(TrivialProp.TrueProp)), 35892, costDetails, 1785))), existingFeature((x: Boolean) => sigmaProp(x), "{ (x: Boolean) => sigmaProp(x) }", FuncValue(Vector((1, SBoolean)), BoolToSigmaProp(ValUse(1, SBoolean))))) } property("atLeast equivalence") { - def success[T](v: T) = Expected(Success(v), 36462) + def costDetails(i: Int) = TracedCost( + traceBase ++ Array( + FixedCostItem(SizeOf), + FixedCostItem(Constant), + TypeBasedCostItem(ArithOp.Minus, SInt), + FixedCostItem(ValUse), + SeqCostItem(CompanionDesc(AtLeast), PerItemCost(JitCost(20), JitCost(3), 5), i) + ) + ) verifyCases( Seq( @@ -7134,7 +9211,7 @@ class SigmaDslSpecification extends SigmaDslTesting Helpers.decodeECPoint("02614b14a8c6c6b4b7ce017d72fbca7f9218b72c16bdd88f170ffb300b106b9014"), Helpers.decodeECPoint("034cc5572276adfa3e283a3f1b0f0028afaadeaa362618c5ec43262d8cefe7f004") ) - )) -> success(CSigmaProp(TrivialProp.TrueProp)), + )) -> Expected(Success(CSigmaProp(TrivialProp.TrueProp)), 36462, costDetails(1), 1790), Coll[SigmaProp]( CSigmaProp( ProveDHTuple( @@ -7146,7 +9223,7 @@ class SigmaDslSpecification extends SigmaDslTesting ), CSigmaProp(ProveDlog(Helpers.decodeECPoint("03f7eacae7476a9ef082513a6a70ed6b208aafad0ade5f614ac6cfa2176edd0d69"))), CSigmaProp(ProveDlog(Helpers.decodeECPoint("023bddd50b917388cd2c4f478f3ea9281bf03a252ee1fefe9c79f800afaa8d86ad"))) - ) -> success( + ) -> Expected(Success( CSigmaProp( CTHRESHOLD( 2, @@ -7162,7 +9239,7 @@ class SigmaDslSpecification extends SigmaDslTesting ) ) ) - ), + ), 36462, costDetails(3), 1893), Colls.replicate[SigmaProp](AtLeast.MaxChildrenCount + 1, CSigmaProp(TrivialProp.TrueProp)) -> Expected(new IllegalArgumentException("Expected input elements count should not exceed 255, actual: 256")) ), @@ -7178,10 +9255,23 @@ class SigmaDslSpecification extends SigmaDslTesting } property("&& sigma equivalence") { + val testTraceBase = traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField) + ) + + val costDetails1 = TracedCost(testTraceBase :+ SeqCostItem(CompanionDesc(SigmaAnd), PerItemCost(JitCost(10), JitCost(2), 1), 2)) + val costDetails2 = TracedCost( + testTraceBase ++ Array( + FixedCostItem(BoolToSigmaProp), + SeqCostItem(CompanionDesc(SigmaAnd), PerItemCost(JitCost(10), JitCost(2), 1), 2) + ) + ) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36428) + def success[T](v: T, newCost: Int) = Expected(Success(v), 36428, costDetails1, newCost) Seq( (CSigmaProp(ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798"))), CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> @@ -7193,20 +9283,19 @@ class SigmaDslSpecification extends SigmaDslTesting ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")) ) ) - ) - ), + ), 1822), (CSigmaProp(TrivialProp.TrueProp), CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), 1804), (CSigmaProp(TrivialProp.FalseProp), CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - success(CSigmaProp(TrivialProp.FalseProp)), + success(CSigmaProp(TrivialProp.FalseProp), 1787), (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), CSigmaProp(TrivialProp.TrueProp)) -> - success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), 1804), (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), CSigmaProp(TrivialProp.FalseProp)) -> - success(CSigmaProp(TrivialProp.FalseProp)) + success(CSigmaProp(TrivialProp.FalseProp), 1787) ) }, existingFeature( @@ -7224,12 +9313,11 @@ class SigmaDslSpecification extends SigmaDslTesting verifyCases( { - def success[T](v: T) = Expected(Success(v), 36522) Seq( (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), true) -> - success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + Expected(Success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), 36522, costDetails2, 1806), (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), false) -> - success(CSigmaProp(TrivialProp.FalseProp)) + Expected(Success(CSigmaProp(TrivialProp.FalseProp)), 36522, costDetails2, 1789) ) }, existingFeature( @@ -7249,9 +9337,16 @@ class SigmaDslSpecification extends SigmaDslTesting } property("|| sigma equivalence") { + val testTraceBase = traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ValUse), + FixedCostItem(SelectField) + ) + + val costDetails1 = TracedCost(testTraceBase :+ SeqCostItem(CompanionDesc(SigmaOr), PerItemCost(JitCost(10), JitCost(2), 1), 2)) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36494) + def success[T](v: T, newCost: Int) = Expected(Success(v), 36494, costDetails1, newCost) Seq( (CSigmaProp(ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798"))), CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> @@ -7263,20 +9358,20 @@ class SigmaDslSpecification extends SigmaDslTesting ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")) ) ) - ) - ), + ), + 1822), (CSigmaProp(TrivialProp.FalseProp), CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), 1804), (CSigmaProp(TrivialProp.TrueProp), CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - success(CSigmaProp(TrivialProp.TrueProp)), + success(CSigmaProp(TrivialProp.TrueProp), 1787), (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), CSigmaProp(TrivialProp.FalseProp)) -> - success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), 1804), (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), CSigmaProp(TrivialProp.TrueProp)) -> - success(CSigmaProp(TrivialProp.TrueProp)) + success(CSigmaProp(TrivialProp.TrueProp), 1787) ) }, existingFeature( @@ -7292,14 +9387,20 @@ class SigmaDslSpecification extends SigmaDslTesting ) ))) + val costDetails2 = TracedCost( + testTraceBase ++ Array( + FixedCostItem(BoolToSigmaProp), + SeqCostItem(CompanionDesc(SigmaOr), PerItemCost(JitCost(10), JitCost(2), 1), 2) + ) + ) verifyCases( { - def success[T](v: T) = Expected(Success(v), 36588) + def success[T](v: T, newCost: Int) = Expected(Success(v), 36588, costDetails2, newCost) Seq( (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), false) -> - success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), 1806), (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), true) -> - success(CSigmaProp(TrivialProp.TrueProp)) + success(CSigmaProp(TrivialProp.TrueProp), 1789) ) }, existingFeature( @@ -7321,17 +9422,7 @@ class SigmaDslSpecification extends SigmaDslTesting property("SigmaProp.propBytes equivalence") { verifyCases( { - def newCost(nItems: Int) = TracedCost( - Array( - FixedCostItem(Apply), - FixedCostItem(FuncValue), - FixedCostItem(GetVar), - FixedCostItem(OptionGet), - FixedCostItem(FuncValue.AddToEnvironmentDesc, FuncValue.AddToEnvironmentDesc_CostKind), - FixedCostItem(ValUse), - SeqCostItem(SigmaPropBytes, nItems) - ) - ) + def newDetails(nItems: Int) = TracedCost(traceBase :+ SeqCostItem(SigmaPropBytes, nItems)) def pk = ProveDlog(Helpers.decodeECPoint("039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6f")) def dht = ProveDHTuple( Helpers.decodeECPoint("03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb"), @@ -7347,25 +9438,25 @@ class SigmaDslSpecification extends SigmaDslTesting Helpers.decodeBytes( "0008ce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b0441" ) - ), cost = 35902, newCost(4)), + ), cost = 35902, newDetails(4), expectedNewCost = 1791), CSigmaProp(pk) -> Expected(Success( Helpers.decodeBytes("0008cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6f")), - cost = 35902, newCost(1)), + cost = 35902, newDetails(1), expectedNewCost = 1789), CSigmaProp(and) -> Expected(Success( Helpers.decodeBytes( "00089602cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b0441" ) - ), cost = 35902, newCost(6)), + ), cost = 35902, newDetails(6), expectedNewCost = 1792), CSigmaProp(threshold) -> Expected(Success( Helpers.decodeBytes( "0008980204cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b04419702cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b04419602cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b0441" ) - ), cost = 35902, newCost(18)), + ), cost = 35902, newDetails(18), expectedNewCost = 1800), CSigmaProp(COR(Array(pk, dht, and, or, threshold))) -> Expected(Success( Helpers.decodeBytes( "00089705cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b04419602cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b04419702cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b0441980204cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b04419702cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b04419602cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6fce03c046fccb95549910767d0543f5e8ce41d66ae6a8720a46f4049cac3b3d26dafb023479c9c3b86a0d3c8be3db0a2d186788e9af1db76d55f3dad127d15185d83d0303d7898641cb6653585a8e1dabfa7f665e61e0498963e329e6e3744bd764db2d72037ae057d89ec0b46ff8e9ff4c37e85c12acddb611c3f636421bef1542c11b0441" ) - ), cost = 35902, newCost(36)) + ), cost = 35902, newDetails(36), expectedNewCost = 1811) ) }, existingFeature((x: SigmaProp) => x.propBytes, @@ -7393,21 +9484,20 @@ class SigmaDslSpecification extends SigmaDslTesting } property("allOf equivalence") { - def success[T](v: T, c: Int) = Expected(Success(v), c) - + def costDetails(i: Int) = TracedCost(traceBase :+ SeqCostItem(CompanionDesc(AND), PerItemCost(JitCost(10), JitCost(5), 32), i)) verifyCases( Seq( - (Coll[Boolean]() -> success(true, 36018)), - (Coll[Boolean](true) -> success(true, 36028)), - (Coll[Boolean](false) -> success(false, 36028)), - (Coll[Boolean](false, false) -> success(false, 36038)), - (Coll[Boolean](false, true) -> success(false, 36038)), - (Coll[Boolean](true, false) -> success(false, 36038)), - (Coll[Boolean](true, true) -> success(true, 36038)), - (Coll[Boolean](true, false, false) -> success(false, 36048)), - (Coll[Boolean](true, false, true) -> success(false, 36048)), - (Coll[Boolean](true, true, false) -> success(false, 36048)), - (Coll[Boolean](true, true, true) -> success(true, 36048)) + (Coll[Boolean]() -> Expected(Success(true), 36018, costDetails(0), 1785)), + (Coll[Boolean](true) -> Expected(Success(true), 36028, costDetails(1), 1785)), + (Coll[Boolean](false) -> Expected(Success(false), 36028, costDetails(1), 1785)), + (Coll[Boolean](false, false) -> Expected(Success(false), 36038, costDetails(1), 1785)), + (Coll[Boolean](false, true) -> Expected(Success(false), 36038, costDetails(1), 1785)), + (Coll[Boolean](true, false) -> Expected(Success(false), 36038, costDetails(2), 1785)), + (Coll[Boolean](true, true) -> Expected(Success(true), 36038, costDetails(2), 1785)), + (Coll[Boolean](true, false, false) -> Expected(Success(false), 36048, costDetails(2), 1785)), + (Coll[Boolean](true, false, true) -> Expected(Success(false), 36048, costDetails(2), 1785)), + (Coll[Boolean](true, true, false) -> Expected(Success(false), 36048, costDetails(3), 1785)), + (Coll[Boolean](true, true, true) -> Expected(Success(true), 36048, costDetails(3), 1785)) ), existingFeature((x: Coll[Boolean]) => SigmaDsl.allOf(x), "{ (x: Coll[Boolean]) => allOf(x) }", @@ -7415,21 +9505,20 @@ class SigmaDslSpecification extends SigmaDslTesting } property("anyOf equivalence") { - def success[T](v: T, c: Int) = Expected(Success(v), c) - + def costDetails(i: Int) = TracedCost(traceBase :+ SeqCostItem(CompanionDesc(OR), PerItemCost(JitCost(5), JitCost(5), 64), i)) verifyCases( Seq( - (Coll[Boolean]() -> success(false, 36062)), - (Coll[Boolean](true) -> success(true, 36072)), - (Coll[Boolean](false) -> success(false, 36072)), - (Coll[Boolean](false, false) -> success(false, 36082)), - (Coll[Boolean](false, true) -> success(true, 36082)), - (Coll[Boolean](true, false) -> success(true, 36082)), - (Coll[Boolean](true, true) -> success(true, 36082)), - (Coll[Boolean](true, false, false) -> success(true, 36092)), - (Coll[Boolean](true, false, true) -> success(true, 36092)), - (Coll[Boolean](true, true, false) -> success(true, 36092)), - (Coll[Boolean](true, true, true) -> success(true, 36092)) + (Coll[Boolean]() -> Expected(Success(false), 36062, costDetails(0), 1784)), + (Coll[Boolean](true) -> Expected(Success(true), 36072, costDetails(1), 1784)), + (Coll[Boolean](false) -> Expected(Success(false), 36072, costDetails(1), 1784)), + (Coll[Boolean](false, false) -> Expected(Success(false), 36082, costDetails(2), 1784)), + (Coll[Boolean](false, true) -> Expected(Success(true), 36082, costDetails(2), 1784)), + (Coll[Boolean](true, false) -> Expected(Success(true), 36082, costDetails(1), 1784)), + (Coll[Boolean](true, true) -> Expected(Success(true), 36082, costDetails(1), 1784)), + (Coll[Boolean](true, false, false) -> Expected(Success(true), 36092, costDetails(1), 1784)), + (Coll[Boolean](true, false, true) -> Expected(Success(true), 36092, costDetails(1), 1784)), + (Coll[Boolean](true, true, false) -> Expected(Success(true), 36092, costDetails(1), 1784)), + (Coll[Boolean](true, true, true) -> Expected(Success(true), 36092, costDetails(1), 1784)) ), existingFeature((x: Coll[Boolean]) => SigmaDsl.anyOf(x), "{ (x: Coll[Boolean]) => anyOf(x) }", @@ -7437,12 +9526,15 @@ class SigmaDslSpecification extends SigmaDslTesting } property("proveDlog equivalence") { + val costDetails = TracedCost(traceBase :+ FixedCostItem(CreateProveDlog)) verifyCases( Seq( (Helpers.decodeGroupElement("02288f0e55610c3355c89ed6c5de43cf20da145b8c54f03a29f481e540d94e9a69") -> Expected(Success( CSigmaProp(ProveDlog(Helpers.decodeECPoint("02288f0e55610c3355c89ed6c5de43cf20da145b8c54f03a29f481e540d94e9a69")))), - cost = 45935)) + cost = 45935, + costDetails, + 1802)) ), existingFeature({ (x: GroupElement) => SigmaDsl.proveDlog(x) }, "{ (x: GroupElement) => proveDlog(x) }", @@ -7450,6 +9542,14 @@ class SigmaDslSpecification extends SigmaDslTesting } property("proveDHTuple equivalence") { + val costDetails = TracedCost( + traceBase ++ Array( + FixedCostItem(ValUse), + FixedCostItem(ValUse), + FixedCostItem(ValUse), + FixedCostItem(CreateProveDHTuple) + ) + ) verifyCases( Seq( (Helpers.decodeGroupElement("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a") @@ -7462,7 +9562,9 @@ class SigmaDslSpecification extends SigmaDslTesting Helpers.decodeECPoint("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a") ) )), - cost = 76215 + cost = 76215, + costDetails, + 1856 )) ), existingFeature({ (x: GroupElement) => SigmaDsl.proveDHTuple(x, x, x, x) }, @@ -7490,10 +9592,21 @@ class SigmaDslSpecification extends SigmaDslTesting ErgoTree.ConstantSegregationHeader, Vector(IntConstant(10)), BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), IntConstant(20)))) - + def costDetails(i: Int) = TracedCost( + traceBase ++ Array( + FixedCostItem(SelectField), + FixedCostItem(ConcreteCollection), + FixedCostItem(ValUse), + FixedCostItem(SelectField), + FixedCostItem(ConcreteCollection), + FixedCostItem(Constant), + FixedCostItem(BoolToSigmaProp), + SeqCostItem(CompanionDesc(SubstConstants), PerItemCost(JitCost(100), JitCost(100), 1), i) + ) + ) verifyCases( { - def success[T](v: T) = Expected(Success(v), 37694) + def success[T](v: T, cd: CostDetails, cost: Int) = Expected(Success(v), 37694, cd, cost) Seq( (Helpers.decodeBytes(""), 0) -> Expected(new java.nio.BufferUnderflowException()), @@ -7502,30 +9615,30 @@ class SigmaDslSpecification extends SigmaDslTesting (Coll(t1.bytes:_*), 0) -> Expected( Success(Helpers.decodeBytes("000008d3")), cost = 37694, - newDetails = CostDetails.ZeroCost, + expectedDetails = CostDetails.ZeroCost, newCost = 1803, newVersionedResults = { - val res = (ExpectedResult(Success(Helpers.decodeBytes("0008d3")), Some(1803)) -> None) + val res = (ExpectedResult(Success(Helpers.decodeBytes("0008d3")), Some(1803)) -> Some(costDetails(0))) Seq(0, 1, 2).map(version => version -> res) }), (Helpers.decodeBytes("000008d3"), 0) -> Expected( Success(Helpers.decodeBytes("00000008d3")), cost = 37694, - newDetails = CostDetails.ZeroCost, + expectedDetails = CostDetails.ZeroCost, newCost = 1803, newVersionedResults = { // since the tree without constant segregation, substitution has no effect - val res = (ExpectedResult(Success(Helpers.decodeBytes("000008d3")), Some(1803)) -> None) + val res = (ExpectedResult(Success(Helpers.decodeBytes("000008d3")), Some(1803)) -> Some(costDetails(0))) Seq(0, 1, 2).map(version => version -> res) }), // tree with segregation flag, empty constants array - (Coll(t2.bytes:_*), 0) -> success(Helpers.decodeBytes("100008d3")), - (Helpers.decodeBytes("100008d3"), 0) -> success(Helpers.decodeBytes("100008d3")), + (Coll(t2.bytes:_*), 0) -> success(Helpers.decodeBytes("100008d3"), costDetails(0), 1803), + (Helpers.decodeBytes("100008d3"), 0) -> success(Helpers.decodeBytes("100008d3"), costDetails(0), 1803), // tree with one segregated constant - (Coll(t3.bytes:_*), 0) -> success(Helpers.decodeBytes("100108d27300")), - (Helpers.decodeBytes("100108d37300"), 0) -> success(Helpers.decodeBytes("100108d27300")), - (Coll(t3.bytes:_*), 1) -> success(Helpers.decodeBytes("100108d37300")), + (Coll(t3.bytes:_*), 0) -> success(Helpers.decodeBytes("100108d27300"), costDetails(1), 1813), + (Helpers.decodeBytes("100108d37300"), 0) -> success(Helpers.decodeBytes("100108d27300"), costDetails(1), 1813), + (Coll(t3.bytes:_*), 1) -> success(Helpers.decodeBytes("100108d37300"), costDetails(1), 1813), (Coll(t4.bytes:_*), 0) -> Expected(new IllegalArgumentException("requirement failed: expected new constant to have the same SInt$ tpe, got SSigmaProp")) ) }, @@ -7550,35 +9663,51 @@ class SigmaDslSpecification extends SigmaDslTesting ))) } - /* Original issue: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/604 - * - * Test fails for v4.x with - * `new StagingException("Don't know how to evaluate(s1252 -> Placeholder(BaseElemLiftable))")` - * but that cannot be explicitly stated in cases. Therefore we use different exception (None.get) - * and also `allowDifferentErrors` flag. - * Test passes for v5.x so we use flag `allowNewToSucceed`. - */ + // Original issue: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/604 property("Random headers access and comparison (originaly from spam tests)") { val (_, _, _, ctx, _, _) = contextData() + val costDetails = TracedCost( + Array( + FixedCostItem(Apply), + FixedCostItem(FuncValue), + FixedCostItem(GetVar), + FixedCostItem(OptionGet), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + SeqCostItem(CompanionDesc(BlockValue), PerItemCost(JitCost(1), JitCost(1), 10), 1), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + FixedCostItem(SContext.headersMethod, FixedCost(JitCost(15))), + FixedCostItem(FuncValue.AddToEnvironmentDesc, FixedCost(JitCost(5))), + FixedCostItem(ValUse), + FixedCostItem(PropertyCall), + SeqCostItem(MethodDesc(SCollection.IndicesMethod), PerItemCost(JitCost(20), JitCost(2), 16), 1), + FixedCostItem(Constant), + FixedCostItem(ValUse), + FixedCostItem(SizeOf), + FixedCostItem(Constant), + TypeBasedCostItem(ArithOp.Minus, SInt), + SeqCostItem(CompanionDesc(Slice), PerItemCost(JitCost(10), JitCost(2), 100), 0), + FixedCostItem(FuncValue), + SeqCostItem(CompanionDesc(ForAll), PerItemCost(JitCost(3), JitCost(1), 10), 0) + ) + ) if (lowerMethodCallsInTests) { + val ir = IR + val error = new ir.StagingException("Don't know how to evaluate(s2034 -> Placeholder(BaseElemLiftable))", Nil) verifyCases( Seq( ctx -> Expected( - Failure(new NoSuchElementException("None.get")), + Failure(error), cost = 37694, - newDetails = CostDetails.ZeroCost, + expectedDetails = CostDetails.ZeroCost, newCost = 1796, - newVersionedResults = Seq( - 0 -> (ExpectedResult(Success(true), Some(1796)) -> None), - 1 -> (ExpectedResult(Success(true), Some(1796)) -> None), - 2 -> (ExpectedResult(Success(true), Some(1796)) -> None) - ) + newVersionedResults = (0 to 2).map(i => i -> (ExpectedResult(Success(true), Some(1796)) -> Some(costDetails))) ) ), changedFeature( { (x: Context) => - Option.empty[Int].get + throw error true }, { (x: Context) => diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala index cd544b7183..8c7cd58dfb 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala @@ -544,7 +544,8 @@ class SigmaDslTesting extends PropSpec } } case _ => - checkResult(rootCause(newRes), rootCause(oldRes), failOnTestVectors = true) + checkResult(rootCause(newRes), rootCause(oldRes), failOnTestVectors = true, + "ExistingFeature.checkEquality: Comparing newRes with oldRes when failure") } if (logInputOutput) { @@ -565,13 +566,19 @@ class SigmaDslTesting extends PropSpec val (oldRes, _) = checkEq(scalaFunc)(oldF)(input).get oldRes shouldBe expected.value.get - if (!(newImpl eq oldImpl)) { - // check the new implementation with Scala semantic - val (newRes, _) = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { - checkEq(scalaFunc)(newF)(input).get + // check the new implementation with Scala semantic + val (newRes, newDetails) = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + checkEq(scalaFunc)(newF)(input).get + } + newRes shouldBe expected.value.get + expected.newResults(ergoTreeVersionInTests)._2.foreach { expDetails => + if (newDetails.trace != expDetails.trace) { + printCostDetails(script, newDetails) + newDetails.trace shouldBe expDetails.trace } - newRes shouldBe expected.value.get } + + checkVerify(input, expected) } override def testCase(input: A, @@ -579,7 +586,7 @@ class SigmaDslTesting extends PropSpec printTestCases: Boolean, failOnTestVectors: Boolean): Unit = { val res = checkEquality(input, printTestCases).map(_._1) - checkResult(res, expectedResult, failOnTestVectors) + checkResult(res, expectedResult, failOnTestVectors, "ExistingFeature#testCase: ") } override def verifyCase(input: A, @@ -588,27 +595,27 @@ class SigmaDslTesting extends PropSpec failOnTestVectors: Boolean): Unit = { val funcRes = checkEquality(input, printTestCases) // NOTE: funcRes comes from newImpl - checkResult(funcRes.map(_._1), expected.value, failOnTestVectors) + checkResult(funcRes.map(_._1), expected.value, failOnTestVectors, + "ExistingFeature#verifyCase: ") val newRes = expected.newResults(ergoTreeVersionInTests) val expectedTrace = newRes._2.fold(Seq.empty[CostItem])(_.trace) if (expectedTrace.isEmpty) { // new cost expectation is missing, print out actual cost results if (evalSettings.printTestVectors) { - funcRes.foreach { case (_, newCost) => - printCostDetails(script, newCost) + funcRes.foreach { case (_, newDetails) => + printCostDetails(script, newDetails) } } } else { // new cost expectation is specified, compare it with the actual result -// TODO mainnet v5.0: uncomment to enable test vectors -// funcRes.foreach { case (_, newCost) => -// if (newCost.trace != expectedTrace) { -// printCostDetails(script, newCost) -// newCost.trace shouldBe expectedTrace -// } -// } + funcRes.foreach { case (_, newDetails) => + if (newDetails.trace != expectedTrace) { + printCostDetails(script, newDetails) + newDetails.trace shouldBe expectedTrace + } + } } checkVerify(input, expected) @@ -635,6 +642,7 @@ class SigmaDslTesting extends PropSpec * accepting without check. * This approach allows to fix bugs in the implementation of * some of v4.x operations. + * @param allowDifferentErrors if true, allow v4.x and v5.0 to fail with different error */ case class ChangedFeature[A, B]( script: String, @@ -650,6 +658,7 @@ class SigmaDslTesting extends PropSpec implicit val cs = compilerSettingsInTests + /** Apply given function to the context variable 1 */ private def getApplyExpr(funcValue: SValue) = { val sType = Evaluation.rtypeToSType(RType[A]) Apply(funcValue, IndexedSeq(OptionGet(GetVar[SType](1.toByte, sType)))) @@ -677,7 +686,7 @@ class SigmaDslTesting extends PropSpec } } - def checkEquality(input: A, logInputOutput: Boolean = false): Try[(B, CostDetails)] = { + override def checkEquality(input: A, logInputOutput: Boolean = false): Try[(B, CostDetails)] = { // check the old implementation against Scala semantic function var oldRes: Try[(B, CostDetails)] = null if (ergoTreeVersionInTests < VersionContext.JitActivationVersion) @@ -723,22 +732,54 @@ class SigmaDslTesting extends PropSpec newRes } - /** compares the old and new implementations against - * semantic function (scalaFunc) on the given input, also checking the given expected result. + /** compares the old and new implementations against semantic functions (scalaFunc and + * scalaFuncNew) on the given input, also checking the given expected result. */ override def checkExpected(input: A, expected: Expected[B]): Unit = { - // check the old implementation with Scala semantic - val (oldRes, _) = checkEq(scalaFunc)(oldF)(input).get - oldRes shouldBe expected.value.get + // check the new implementation with Scala semantic function + val newRes = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + checkEq(scalaFuncNew)(newF)(input) + } - if (!(newImpl eq oldImpl)) { - // check the new implementation with Scala semantic - val (newRes, _) = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { - checkEq(scalaFuncNew)(newF)(input).get + if (!VersionContext.current.isJitActivated) { + // check the old implementation with Scala semantic + val expectedOldRes = expected.value + val oldRes = checkEq(scalaFunc)(oldF)(input) + checkResult(oldRes.map(_._1), expectedOldRes, failOnTestVectors = true, + "Comparing oldRes with expected: !isJitActivated: ") + + val newValue = newRes.map(_._1) + (expectedOldRes, newValue) match { + case (_: Failure[_], _: Success[_]) if allowNewToSucceed => + // NOTE, we are in ChangedFeature (compare with ExistingFeature) + // this is the case when old v4.x version fails with exception (e.g. due to AOT costing), + // but the new v5.0 produces result. (See property("Option fold workaround method")) + // Thus, we allow some scripts which fail in v4.x to pass in v5.0. + // see ScalaDoc for allowNewToSucceed + case (_: Failure[_], _: Failure[_]) if allowDifferentErrors => + // this is the case when old v4.x version fails with one exception (e.g. due to AOT costing), + // but the new v5.0 fails with another exception. + case _ => + checkResult(newValue, expectedOldRes, failOnTestVectors = true, + "Comparing newRes with expected old result: !isJitActivated: ") + } + } else { + val (newExpectedRes, newExpectedDetailsOpt) = expected.newResults(ergoTreeVersionInTests) + newRes match { + case Success((newValue, newDetails)) => + newValue shouldBe newExpectedRes.value.get + newExpectedDetailsOpt.foreach { expDetails => + if (newDetails.trace != expDetails.trace) { + printCostDetails(script, newDetails) + newDetails.trace shouldBe expDetails.trace + } + } + case _ => + checkResult(newRes.map(_._1), newExpectedRes.value, failOnTestVectors = true, + "Comparing newRes with new expected: isJitActivated: ") } - val newExpectedRes = expected.newResults(ergoTreeVersionInTests) - newRes shouldBe newExpectedRes._1.value.get } + checkVerify(input, expected) } override def testCase(input: A, @@ -746,14 +787,15 @@ class SigmaDslTesting extends PropSpec printTestCases: Boolean, failOnTestVectors: Boolean): Unit = { val res = checkEquality(input, printTestCases).map(_._1) - checkResult(res, expectedResult, failOnTestVectors) + checkResult(res, expectedResult, failOnTestVectors, + "ChangedFeature#testCase: ") } override def verifyCase(input: A, expected: Expected[B], printTestCases: Boolean, failOnTestVectors: Boolean): Unit = { - checkEquality(input, printTestCases) + checkExpected(input, expected) checkVerify(input, expected) } } @@ -801,6 +843,7 @@ class SigmaDslTesting extends PropSpec val newExpectedRes = expected.newResults(ergoTreeVersionInTests) newRes shouldBe newExpectedRes._1.value.get } + checkVerify(input, expected) } override def testCase(input: A, @@ -909,19 +952,19 @@ class SigmaDslTesting extends PropSpec * * @param value value returned by feature function v4.x * @param cost expected cost value of the verification execution (v4.x) - * @param newDetails expected cost details for all versions + * @param expectedDetails expected cost details for all versions * @param newCost expected new verification cost for all versions * @param newVersionedResults new results returned by each changed feature function in * v5.+ for each ErgoTree version. */ def apply[A](value: Try[A], cost: Int, - newDetails: CostDetails, newCost: Int, + expectedDetails: CostDetails, newCost: Int, newVersionedResults: Seq[(Int, (ExpectedResult[A], Option[CostDetails]))]): Expected[A] = new Expected[A](ExpectedResult(value, Some(cost))) { override val newResults = { val commonNewResults = defaultNewResults.map { case (res, _) => - (ExpectedResult(res.value, Some(newCost)), Option(newDetails)) + (ExpectedResult(res.value, Some(newCost)), Option(expectedDetails)) } commonNewResults.updateMany(newVersionedResults) } @@ -991,13 +1034,16 @@ class SigmaDslTesting extends PropSpec /** NOTE, this should be `def` to allow overriding of generatorDrivenConfig in derived Spec classes. */ def DefaultMinSuccessful: MinSuccessful = MinSuccessful(generatorDrivenConfig.minSuccessful) - val PrintTestCasesDefault: Boolean = false // true + val PrintTestCasesDefault: Boolean = false val FailOnTestVectorsDefault: Boolean = true - protected def checkResult[B](res: Try[B], expectedRes: Try[B], failOnTestVectors: Boolean, hint: String = ""): Unit = { + /** Because this method is called from many places it should always be called with `hint`. */ + protected def checkResult[B](res: Try[B], expectedRes: Try[B], failOnTestVectors: Boolean, hint: String): Unit = { (res, expectedRes) match { case (Failure(exception), Failure(expectedException)) => - rootCause(exception).getClass shouldBe rootCause(expectedException).getClass + withClue(hint) { + rootCause(exception).getClass shouldBe rootCause(expectedException).getClass + } case _ => if (failOnTestVectors) { val actual = rootCause(res)