diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala index 978ec0dfe5..90fb04a8fd 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoBox.scala @@ -1,10 +1,10 @@ package org.ergoplatform import com.google.common.primitives.Shorts -import org.ergoplatform.ErgoBox.{NonMandatoryRegisterId, TokenId} +import org.ergoplatform.ErgoBox.{TokenId, NonMandatoryRegisterId} import org.ergoplatform.settings.ErgoAlgos import scorex.crypto.authds.ADKey -import scorex.crypto.hash.{Blake2b256, Digest32} +import scorex.crypto.hash.{Digest32, Blake2b256} import scorex.util._ import sigmastate.SCollection.SByteArray import sigmastate.SType.AnyOps @@ -13,7 +13,7 @@ import sigmastate._ import sigmastate.eval.Extensions._ import sigmastate.eval._ import sigmastate.serialization.SigmaSerializer -import sigmastate.utils.{Helpers, SigmaByteReader, SigmaByteWriter} +import sigmastate.utils.{SigmaByteReader, SigmaByteWriter, Helpers} import sigmastate.utxo.ExtractCreationInfo import special.collection._ @@ -127,6 +127,8 @@ object ErgoBox { abstract class MandatoryRegisterId(override val number: Byte, val purpose: String) extends RegisterId abstract class NonMandatoryRegisterId(override val number: Byte) extends RegisterId + type AdditionalRegisters = Map[NonMandatoryRegisterId, _ <: EvaluatedValue[_ <: SType]] + object R0 extends MandatoryRegisterId(0, "Monetary value, in Ergo tokens") object R1 extends MandatoryRegisterId(1, "Guarding script") object R2 extends MandatoryRegisterId(2, "Secondary tokens") @@ -175,18 +177,6 @@ object ErgoBox { val allZerosModifierId: ModifierId = Array.fill[Byte](32)(0.toByte).toModifierId - def apply(value: Long, - ergoTree: ErgoTree, - creationHeight: Int, - additionalTokens: Seq[(TokenId, Long)] = Nil, - additionalRegisters: Map[NonMandatoryRegisterId, _ <: EvaluatedValue[_ <: SType]] = Map.empty, - transactionId: ModifierId = allZerosModifierId, - boxIndex: Short = 0): ErgoBox = - new ErgoBox(value, ergoTree, - Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]), - additionalRegisters, - transactionId, boxIndex, creationHeight) - object sigmaSerializer extends SigmaSerializer[ErgoBox, ErgoBox] { override def serialize(obj: ErgoBox, w: SigmaByteWriter): Unit = { diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index fc2087df74..1fad322b59 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -10,7 +10,7 @@ import scorex.crypto.authds.avltree.batch._ import scorex.crypto.authds.{ADDigest, ADKey, SerializedAdProof, ADValue} import sigmastate.SCollection.SByteArray import sigmastate.{TrivialProp, _} -import sigmastate.Values.{Constant, EvaluatedValue, SValue, ConstantNode, Value, ErgoTree, SigmaBoolean} +import sigmastate.Values.{Constant, EvaluatedValue, SValue, ConstantNode, ErgoTree, SigmaBoolean} import sigmastate.interpreter.CryptoConstants.EcPointType import sigmastate.interpreter.{CryptoConstants, Interpreter} import special.collection.{Size, CSizeOption, SizeColl, CCostedBuilder, CollType, SizeOption, CostedBuilder, Coll} @@ -738,4 +738,33 @@ case class CostingDataContext( } else None } } + + /** Return a new context instance with variables collection updated. + * @param bindings a new binding of the context variables with new values. + * @return a new instance (if `bindings` non-empty) with the specified bindings. + * other existing bindings are copied to the new instance + */ + def withUpdatedVars(bindings: (Int, AnyValue)*): CostingDataContext = { + if (bindings.isEmpty) return this + + val ids = bindings.map(_._1).toArray + val values = bindings.map(_._2).toArray + val maxVarId = ids.max // INV: ids is not empty + val requiredNewLength = maxVarId + 1 + + val newVars = if (vars.length < requiredNewLength) { + // grow vars collection + val currVars = vars.toArray + val buf = new Array[AnyValue](requiredNewLength) + Array.copy(currVars, 0, buf, 0, currVars.length) + cfor(0)(_ < ids.length, _ + 1) { i => + buf(ids(i)) = values(i) + } + buf.toColl + } else { + vars.updateMany(ids.toColl, values.toColl) + } + + this.copy(vars = newVars) + } } diff --git a/sigmastate/src/main/scala/sigmastate/eval/IRContext.scala b/sigmastate/src/main/scala/sigmastate/eval/IRContext.scala index 9fb39dfe78..3f5b27b762 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/IRContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/IRContext.scala @@ -116,7 +116,7 @@ trait IRContext extends Evaluation with TreeBuilding { * And taking into account the cleaning of the garbage and cutting the blockchain history, * the old scripts at some point will die out of the blockchain. */ - def checkCostWithContext(ctx: SContext, exp: Value[SType], + def checkCostWithContext(ctx: SContext, costF: Ref[((Context, (Int, Size[Context]))) => Int], maxCost: Long, initCost: Long): Try[Int] = Try { val costFun = compile[(SContext, (Int, SSize[SContext])), Int, (Context, (Int, Size[Context])), Int]( getDataEnv, costF, Some(maxCost)) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index e0137a0b75..ab4dc4f1de 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -157,7 +157,7 @@ trait Interpreter extends ScorexLogging { CheckCostFunc(IR)(asRep[Any => Int](costF)) val costingCtx = context.toSigmaContext(IR, isCost = true) - val estimatedCost = IR.checkCostWithContext(costingCtx, exp, costF, maxCost, initCost).getOrThrow + val estimatedCost = IR.checkCostWithContext(costingCtx, costF, maxCost, initCost).getOrThrow IR.onEstimatedCost(env, exp, costingRes, costingCtx, estimatedCost) diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala index aeb2cac85f..4358b35f20 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala @@ -14,6 +14,7 @@ import sigmastate.{SigmaAnd, SType} import sigmastate.Values.{UnparsedErgoTree, Constant, ByteArrayConstant, IntConstant, ErgoTree} import sigmastate.eval.IRContext import sigmastate.helpers._ +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.ContextExtension import sigmastate.interpreter.Interpreter.{ScriptNameProp, ScriptEnv} import sigmastate.lang.Terms.ValueOps @@ -182,7 +183,7 @@ class ErgoAddressSpecification extends SigmaDslTesting with TryValues { def testPay2SHAddress(address: Pay2SHAddress, scriptBytes: Array[Byte])(implicit IR: IRContext) = { val scriptId = 1.toByte - val boxToSpend = ErgoBox(10, address.script, creationHeight = 5) + val boxToSpend = testBox(10, address.script, creationHeight = 5) val ctx = ErgoLikeContextTesting.dummy(boxToSpend) .withExtension(ContextExtension(Seq( scriptId -> ByteArrayConstant(scriptBytes) // provide script bytes in context variable diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala index c58455ba76..f0f9b17495 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala @@ -5,17 +5,18 @@ import org.ergoplatform.ErgoBox.R4 import org.ergoplatform.mining.emission.EmissionRules import org.ergoplatform.settings.MonetarySettings import org.scalacheck.Gen -import scorex.crypto.hash.{Blake2b256, Digest32} +import scorex.crypto.hash.{Digest32, Blake2b256} import scorex.util.Random -import sigmastate.Values.{ByteArrayConstant, CollectionConstant, ErgoTree, IntConstant, SigmaPropConstant} +import sigmastate.Values.{SigmaPropConstant, CollectionConstant, ByteArrayConstant, IntConstant, ErgoTree} import sigmastate._ -import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.basics.DLogProtocol.{ProveDlog, DLogProverInput} +import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons, ContextEnrichingTestProvingInterpreter} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigmastate.interpreter.{ProverResult, ContextExtension} import sigmastate.lang.Terms.ValueOps import sigmastate.serialization.ValueSerializer -import sigmastate.utxo.{ByIndex, CostTable, ExtractCreationInfo, SelectField} +import sigmastate.utxo.{CostTable, ExtractCreationInfo, ByIndex, SelectField} import scalan.util.BenchmarkUtil._ import ErgoScriptPredef._ import sigmastate.utils.Helpers._ @@ -42,7 +43,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { val prop = EQ(Height, ErgoScriptPredef.boxCreationHeight(ByIndex(Outputs, IntConstant(0)))).toSigmaProp val propInlined = EQ(Height, SelectField(ExtractCreationInfo(ByIndex(Outputs, IntConstant(0))), 1).asIntValue).toSigmaProp prop shouldBe propInlined - val inputBox = ErgoBox(1, prop, nextHeight, Seq(), Map()) + val inputBox = testBox(1, prop, nextHeight, Seq(), Map()) val inputBoxes = IndexedSeq(inputBox) val inputs = inputBoxes.map(b => Input(b.id, emptyProverResult)) val minerBox = new ErgoBoxCandidate(1, SigmaPropConstant(minerProp), nextHeight) @@ -102,10 +103,10 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { newProp: ErgoTree, inputR4Val: CollectionConstant[SByte.type]): Try[Unit] = Try { val outputR4Val: CollectionConstant[SByte.type] = ByteArrayConstant(Random.randomBytes()) - val inputBoxes = IndexedSeq(ErgoBox(emission.foundersCoinsTotal, prop, 0, Seq(), Map(R4 -> inputR4Val))) + val inputBoxes = IndexedSeq(testBox(emission.foundersCoinsTotal, prop, 0, Seq(), Map(R4 -> inputR4Val))) val inputs = inputBoxes.map(b => Input(b.id, emptyProverResult)) - val newFoundersBox = ErgoBox(remainingAmount, newProp, 0, Seq(), Map(R4 -> outputR4Val)) - val collectedBox = ErgoBox(inputBoxes.head.value - remainingAmount, TrueProp, 0) + val newFoundersBox = testBox(remainingAmount, newProp, 0, Seq(), Map(R4 -> outputR4Val)) + val collectedBox = testBox(inputBoxes.head.value - remainingAmount, TrueProp, 0) val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(newFoundersBox, collectedBox)) val ctx = ErgoLikeContextTesting( currentHeight = height, @@ -124,9 +125,9 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { val minerPk = prover.dlogSecrets.head.publicImage val prop = ErgoScriptPredef.rewardOutputScript(settings.minerRewardDelay, minerPk) val verifier = new ErgoLikeTestInterpreter - val inputBoxes = IndexedSeq(ErgoBox(20, prop, 0, Seq(), Map())) + val inputBoxes = IndexedSeq(testBox(20, prop, 0, Seq(), Map())) val inputs = inputBoxes.map(b => Input(b.id, emptyProverResult)) - val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(ErgoBox(inputBoxes.head.value, TrueProp, 0))) + val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(testBox(inputBoxes.head.value, TrueProp, 0))) val ctx = ErgoLikeContextTesting( currentHeight = inputBoxes.head.creationHeight + settings.minerRewardDelay, @@ -157,7 +158,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { val prover = new ContextEnrichingTestProvingInterpreter val minerPk = prover.dlogSecrets.head.publicImage val prop = ErgoScriptPredef.emissionBoxProp(settings) - val emissionBox = ErgoBox(emission.coinsTotal, prop, 0, Seq(), Map()) + val emissionBox = testBox(emission.coinsTotal, prop, 0, Seq(), Map()) val minerProp = ErgoScriptPredef.rewardOutputScript(settings.minerRewardDelay, minerPk) // collect coins during the fixed rate period @@ -215,7 +216,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { def check(inputBoxes: IndexedSeq[ErgoBox]): Try[Unit] = Try { val inputs = inputBoxes.map(b => Input(b.id, emptyProverResult)) val amount = inputBoxes.map(_.value).sum - val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(ErgoBox(amount, pubkey.toSigmaProp, 0))) + val spendingTransaction = ErgoLikeTransaction(inputs, IndexedSeq(testBox(amount, pubkey.toSigmaProp, 0))) val ctx = ErgoLikeContextTesting( currentHeight = 50, @@ -233,37 +234,37 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { measure(10) { i => // transaction with the only input with enough token should pass val inputs0 = IndexedSeq( - ErgoBox(20, prop, 0, Seq((wrongId, tokenAmount), (tokenId, tokenAmount), (wrongId2, tokenAmount)), Map()) + testBox(20, prop, 0, Seq((wrongId, tokenAmount), (tokenId, tokenAmount), (wrongId2, tokenAmount)), Map()) ) check(inputs0).get shouldBe (()) // transaction with the only input with insufficient token should fail val inputs1 = IndexedSeq( - ErgoBox(20, prop, 0, Seq((wrongId, tokenAmount), (tokenId, tokenAmount - 1)), Map()) + testBox(20, prop, 0, Seq((wrongId, tokenAmount), (tokenId, tokenAmount - 1)), Map()) ) check(inputs1) shouldBe 'failure // transaction with multiple inputs with insufficient token should fail val inputs2 = IndexedSeq( - ErgoBox(20, prop, 0, Seq((wrongId, tokenAmount), (tokenId, tokenAmount - 2)), Map()), - ErgoBox(20, prop, 0, Seq((wrongId, tokenAmount)), Map()), - ErgoBox(20, prop, 0, Seq((tokenId, 1), (wrongId2, tokenAmount)), Map()) + testBox(20, prop, 0, Seq((wrongId, tokenAmount), (tokenId, tokenAmount - 2)), Map()), + testBox(20, prop, 0, Seq((wrongId, tokenAmount)), Map()), + testBox(20, prop, 0, Seq((tokenId, 1), (wrongId2, tokenAmount)), Map()) ) check(inputs2) shouldBe 'failure // transaction with multiple inputs with enough token should pass val inputs3 = IndexedSeq( - ErgoBox(20, prop, 0, Seq((wrongId, 1), (tokenId, tokenAmount / 2)), Map()), - ErgoBox(20, prop, 0, Seq((wrongId, 1)), Map()), - ErgoBox(20, prop, 0, Seq((tokenId, tokenAmount / 2 + 1), (wrongId2, 1)), Map()) + testBox(20, prop, 0, Seq((wrongId, 1), (tokenId, tokenAmount / 2)), Map()), + testBox(20, prop, 0, Seq((wrongId, 1)), Map()), + testBox(20, prop, 0, Seq((tokenId, tokenAmount / 2 + 1), (wrongId2, 1)), Map()) ) check(inputs3).getOrThrow // A transaction which contains input with no tokens val inputs4 = IndexedSeq( - ErgoBox(20, prop, 0, Seq((wrongId, 1), (tokenId, tokenAmount / 2)), Map()), - ErgoBox(20, prop, 0, Seq(), Map()), - ErgoBox(20, prop, 0, Seq((tokenId, tokenAmount / 2 + 1), (wrongId2, 1)), Map()) + testBox(20, prop, 0, Seq((wrongId, 1), (tokenId, tokenAmount / 2)), Map()), + testBox(20, prop, 0, Seq(), Map()), + testBox(20, prop, 0, Seq((tokenId, tokenAmount / 2 + 1), (wrongId2, 1)), Map()) ) check(inputs4) shouldBe 'success } diff --git a/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index 14aec73804..1467acf92c 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -3,24 +3,23 @@ package org.ergoplatform.dsl import sigmastate.interpreter.Interpreter.ScriptNameProp import scala.collection.mutable -import sigmastate.interpreter.{ContextExtension, CostedProverResult, ProverResult} +import sigmastate.interpreter.{ProverResult, CostedProverResult} import scala.collection.mutable.ArrayBuffer import org.ergoplatform.ErgoBox.NonMandatoryRegisterId -import org.ergoplatform.SigmaConstants.ScriptCostLimit import scalan.Nullable import scorex.crypto.hash.Digest32 import scala.util.Try -import org.ergoplatform.{ErgoBox, ErgoLikeContext} -import org.ergoplatform.dsl.ContractSyntax.{ErgoScript, Proposition, Token, TokenId} -import org.ergoplatform.validation.ValidationRules +import org.ergoplatform.{ErgoLikeContext, ErgoBox} +import org.ergoplatform.dsl.ContractSyntax.{Token, TokenId, ErgoScript, Proposition} import sigmastate.{AvlTreeData, SType} import sigmastate.Values.{ErgoTree, EvaluatedValue} -import sigmastate.eval.{CSigmaProp, Evaluation, IRContext} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.eval.{IRContext, CSigmaProp, Evaluation} +import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons, ContextEnrichingTestProvingInterpreter} +import sigmastate.helpers.TestingHelpers._ import sigmastate.lang.Terms.ValueOps -import special.sigma.{AnyValue, SigmaProp, TestValue} +import special.sigma.{AnyValue, TestValue, SigmaProp} case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRContext) extends ContractSpec { @@ -84,7 +83,7 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC minerPubkey = ErgoLikeContextTesting.dummyPubkey, dataBoxes = dataBoxes, boxesToSpend = boxesToSpend, - spendingTransaction = testSuite.createTransaction(dataBoxes, tx.outputs.map(_.ergoBox).toIndexedSeq), + spendingTransaction = createTransaction(dataBoxes, tx.outputs.map(_.ergoBox).toIndexedSeq), selfIndex = boxesToSpend.indexOf(utxoBox.ergoBox) ) ctx } @@ -119,7 +118,7 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC private[dsl] lazy val ergoBox: ErgoBox = { val tokens = _tokens.map { t => (Digest32 @@ t.id.toArray, t.value) } - ErgoBox(value, propSpec.ergoTree, tx.block.height, tokens, _regs) + testBox(value, propSpec.ergoTree, tx.block.height, tokens, _regs) } def id = ergoBox.id } diff --git a/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala index 6715e3cd1c..aa944390cc 100644 --- a/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala @@ -3,20 +3,21 @@ package sigmastate import org.ergoplatform.SigmaConstants.ScriptCostLimit import org.ergoplatform.ErgoScriptPredef.TrueProp import org.ergoplatform.validation.ValidationRules -import org.ergoplatform.{ErgoBox, ErgoLikeContext, ErgoLikeTransaction} +import org.ergoplatform.{ErgoLikeContext, ErgoBox} import scorex.crypto.authds.avltree.batch.Lookup import scorex.crypto.authds.{ADDigest, ADKey} import scorex.crypto.hash.Blake2b256 -import sigmastate.Values.{AvlTreeConstant, BigIntConstant, BooleanConstant, ByteArrayConstant, ConstantPlaceholder, ErgoTree, IntConstant, TrueLeaf} +import sigmastate.Values.{TrueLeaf, BigIntConstant, AvlTreeConstant, ConstantPlaceholder, ByteArrayConstant, IntConstant, ErgoTree, BooleanConstant} import sigmastate.eval.Extensions._ import sigmastate.eval.Sized._ import sigmastate.eval._ +import sigmastate.helpers.TestingHelpers._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter} import sigmastate.interpreter.ContextExtension -import sigmastate.interpreter.Interpreter.{ScriptEnv, ScriptNameProp, emptyEnv} +import sigmastate.interpreter.Interpreter.{ScriptNameProp, ScriptEnv, emptyEnv} import sigmastate.utxo.CostTable import sigmastate.utxo.CostTable._ -import special.sigma.{AvlTree, SigmaTestingData} +import special.sigma.{SigmaTestingData, AvlTree} class CostingSpecification extends SigmaTestingData { implicit lazy val IR = new TestingIRContext { @@ -58,8 +59,8 @@ class CostingSpecification extends SigmaTestingData { Map(ErgoBox.R4 -> ByteArrayConstant(Array[Byte](1, 2, 3)), ErgoBox.R5 -> IntConstant(3), ErgoBox.R6 -> AvlTreeConstant(avlTree))) - lazy val outBoxA = ErgoBox(10, pkA, 0) - lazy val outBoxB = ErgoBox(20, pkB, 0) + lazy val outBoxA = testBox(10, pkA, 0) + lazy val outBoxB = testBox(20, pkB, 0) lazy val tx = createTransaction(IndexedSeq(dataBox), IndexedSeq(outBoxA, outBoxB)) lazy val context = new ErgoLikeContext( diff --git a/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala b/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala index ac846b2b6c..ed166795f3 100644 --- a/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala +++ b/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala @@ -1,9 +1,7 @@ package sigmastate -import org.ergoplatform.{ErgoBox, ErgoLikeContext} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter, SigmaTestingCommons} -import org.ergoplatform.{ErgoBox, ErgoLikeContext, ErgoLikeInterpreter, ErgoLikeTransaction} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.lang.Terms._ import org.scalatest.TryValues._ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} @@ -34,9 +32,9 @@ class FailingToProveSpec extends SigmaTestingCommons { | } """.stripMargin).asBoolValue.toSigmaProp - val selfBox = ErgoBox(200L, compiledScript, 0) - val o1 = ErgoBox(101L, TrueProp, 5001) - val o2 = ErgoBox(99L, TrueProp, 5001) + val selfBox = testBox(200L, compiledScript, 0) + val o1 = testBox(101L, TrueProp, 5001) + val o2 = testBox(99L, TrueProp, 5001) val tx = createTransaction(IndexedSeq(o1, o2)) val ctx = ErgoLikeContextTesting( currentHeight = 5001, @@ -67,10 +65,10 @@ class FailingToProveSpec extends SigmaTestingCommons { | } """.stripMargin).asBoolValue.toSigmaProp - val selfBox = ErgoBox(200L, compiledScript, 0) - val o1 = ErgoBox(102L, TrueProp, 5001) - val o2 = ErgoBox(98L, TrueProp, 5001) - val o3 = ErgoBox(100L, TrueProp, 5001) + val selfBox = testBox(200L, compiledScript, 0) + val o1 = testBox(102L, TrueProp, 5001) + val o2 = testBox(98L, TrueProp, 5001) + val o3 = testBox(100L, TrueProp, 5001) val tx = createTransaction(IndexedSeq(o1, o2, o3)) val ctx = ErgoLikeContextTesting( currentHeight = 5001, diff --git a/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index 95c7fedf70..2cfeaa45fa 100644 --- a/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -8,6 +8,7 @@ import sigmastate.Values.ErgoTree.EmptyConstants import sigmastate.Values.{UnparsedErgoTree, NotReadyValueInt, ByteArrayConstant, Tuple, IntConstant, ErgoTree, ValueCompanion} import sigmastate.eval.Colls import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.interpreter.{ProverResult, ContextExtension} import sigmastate.lang.Terms._ diff --git a/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index 9a2091a0cb..0a14afc166 100644 --- a/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -10,6 +10,7 @@ import sigmastate.lang.Terms._ import org.ergoplatform._ import scorex.util.encode.Base58 import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.serialization.ValueSerializer import TrivialProp._ import sigmastate.utils.Helpers._ @@ -115,7 +116,7 @@ class TestingInterpreterSpecification extends SigmaTestingCommons { "dk2" -> dk2, "bytes1" -> Array[Byte](1, 2, 3), "bytes2" -> Array[Byte](4, 5, 6), - "box1" -> ErgoBox(10, ErgoScriptPredef.TrueProp, 0, Seq(), Map( + "box1" -> testBox(10, ErgoScriptPredef.TrueProp, 0, Seq(), Map( reg1 -> IntArrayConstant(Array[Int](1, 2, 3)), reg2 -> BoolArrayConstant(Array[Boolean](true, false, true))))) val prop = compile(env, code).asBoolValue.toSigmaProp diff --git a/sigmastate/src/test/scala/sigmastate/TypesSpecification.scala b/sigmastate/src/test/scala/sigmastate/TypesSpecification.scala index ec58235a48..63dc2c126e 100644 --- a/sigmastate/src/test/scala/sigmastate/TypesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/TypesSpecification.scala @@ -15,6 +15,7 @@ import sigmastate.Values.{ShortConstant, LongConstant, BigIntConstant, AvlTreeCo import sigmastate.eval.SigmaDsl import special.collection.Coll import special.sigma.BigInt +import sigmastate.helpers.TestingHelpers._ class TypesSpecification extends SigmaTestingData { @@ -54,7 +55,7 @@ class TypesSpecification extends SigmaTestingData { val (tree, _) = createAvlTreeAndProver() - val box = SigmaDsl.Box(ErgoBox(20, TrueProp, 0, + val box = SigmaDsl.Box(testBox(20, TrueProp, 0, Seq( (Digest32 @@ (ErgoAlgos.decodeUnsafe("6e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f0001")), 10000000L) diff --git a/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala b/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala index 3deac131a9..2abaf1c128 100644 --- a/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala @@ -4,19 +4,17 @@ import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix import org.ergoplatform.validation.ValidationSpecification import scala.util.Success -import sigmastate.{SInt, AvlTreeData, SLong, SType} -import sigmastate.Values.{LongConstant, Constant, EvaluatedValue, SValue, TrueLeaf, SigmaPropConstant, Value, IntConstant, ErgoTree, BigIntArrayConstant} +import sigmastate.{AvlTreeData, SType} +import sigmastate.Values.{EvaluatedValue, SValue, SigmaPropConstant, Value, BigIntArrayConstant} import org.ergoplatform.{Context => _, _} import sigmastate.utxo.CostTable import scalan.BaseCtxTests import sigmastate.lang.{LangTests, SigmaCompiler} -import sigmastate.helpers.ContextEnrichingTestProvingInterpreter -import sigmastate.helpers.ErgoLikeContextTesting +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.ContextExtension import sigmastate.interpreter.Interpreter.ScriptEnv -import sigmastate.serialization.ErgoTreeSerializer import special.sigma.{ContractsTestkit, Context => DContext, _} -import sigmastate.eval.Extensions._ import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer import scala.language.implicitConversions @@ -66,10 +64,10 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests lazy val backerPubKey = backerProver.dlogSecrets.head.publicImage lazy val projectPubKey = projectProver.dlogSecrets.head.publicImage - val boxToSpend = ErgoBox(10, ErgoScriptPredef.TrueProp, 0, + val boxToSpend = testBox(10, ErgoScriptPredef.TrueProp, 0, additionalRegisters = Map(ErgoBox.R4 -> BigIntArrayConstant(bigIntegerArr1))) - lazy val tx1Output1 = ErgoBox(minToRaise, projectPubKey, 0) - lazy val tx1Output2 = ErgoBox(1, projectPubKey, 0) + lazy val tx1Output1 = testBox(minToRaise, projectPubKey, 0) + lazy val tx1Output2 = testBox(1, projectPubKey, 0) lazy val tx1 = new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(), IndexedSeq(tx1Output1, tx1Output2)) lazy val ergoCtx = ErgoLikeContextTesting( currentHeight = timeout - 1, diff --git a/sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala b/sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala index 32ff2d3d29..6e794bb7cc 100644 --- a/sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala @@ -3,6 +3,7 @@ package sigmastate.eval import org.ergoplatform.ErgoBox import sigmastate.Values.{ConcreteCollection, IntArrayConstant, IntConstant, SigmaPropConstant, SigmaPropValue} import sigmastate.helpers.ContextEnrichingTestProvingInterpreter +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ import scalan.BaseCtxTests import sigmastate.lang.LangTests @@ -37,7 +38,7 @@ class EvaluationTest extends BaseCtxTests test("lazy logical ops") { val prover = new ContextEnrichingTestProvingInterpreter val pk = prover.dlogSecrets.head.publicImage - val self = ErgoBox(1, pk, 0, additionalRegisters = Map(ErgoBox.R4 -> IntConstant(10))) + val self = testBox(1, pk, 0, additionalRegisters = Map(ErgoBox.R4 -> IntConstant(10))) val ctx = newErgoContext(height = 1, self) // guarded register access: existing reg reduce(emptyEnv, "lazy1", "SELF.R4[Int].isDefined && SELF.R4[Int].get == 10", ctx, true) diff --git a/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala index 257fda7902..97f355331c 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala @@ -42,7 +42,7 @@ object ErgoLikeContextTesting { spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], self: ErgoBox, extension: ContextExtension = ContextExtension.empty, - vs: SigmaValidationSettings = ValidationRules.currentSettings) = + vs: SigmaValidationSettings = ValidationRules.currentSettings): ErgoLikeContext = new ErgoLikeContext(lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), noBoxes, boxesToSpend, spendingTransaction, boxesToSpend.indexOf(self), extension, vs, ScriptCostLimit.value, 0L) @@ -57,7 +57,7 @@ object ErgoLikeContextTesting { dataBoxes, boxesToSpend, spendingTransaction, selfIndex, ContextExtension.empty, ValidationRules.currentSettings, ScriptCostLimit.value, 0L) - def dummy(selfDesc: ErgoBox) = ErgoLikeContextTesting(currentHeight = 0, + def dummy(selfDesc: ErgoBox): ErgoLikeContext = ErgoLikeContextTesting(currentHeight = 0, lastBlockUtxoRoot = AvlTreeData.dummy, dummyPubkey, boxesToSpend = IndexedSeq(selfDesc), spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), self = selfDesc) diff --git a/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala index ef94329e31..18bd3b3596 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala @@ -1,8 +1,8 @@ package sigmastate.helpers import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix -import org.ergoplatform.ErgoBox.NonMandatoryRegisterId import org.ergoplatform.ErgoScriptPredef.TrueProp +import org.ergoplatform.SigmaConstants.ScriptCostLimit import org.ergoplatform._ import org.ergoplatform.validation.ValidationRules.{CheckCostFunc, CheckCalcFunc} import org.ergoplatform.validation.ValidationSpecification @@ -11,9 +11,9 @@ import org.scalacheck.Gen import org.scalatest.prop.{PropertyChecks, GeneratorDrivenPropertyChecks} import org.scalatest.{PropSpec, Assertion, Matchers} import scalan.{TestUtils, TestContexts, RType} -import scorex.crypto.hash.{Digest32, Blake2b256} +import scorex.crypto.hash.Blake2b256 import sigma.types.IsPrimView -import sigmastate.Values.{Constant, EvaluatedValue, SValue, Value, ErgoTree, GroupElementConstant} +import sigmastate.Values.{Constant, EvaluatedValue, SValue, Value, GroupElementConstant} import sigmastate.interpreter.Interpreter.{ScriptNameProp, ScriptEnv} import sigmastate.interpreter.{CryptoConstants, Interpreter} import sigmastate.lang.{Terms, TransformingSigmaBuilder, SigmaCompiler} @@ -21,6 +21,8 @@ import sigmastate.serialization.{ValueSerializer, SigmaSerializer} import sigmastate.{SGroupElement, SType} import sigmastate.eval.{CompiletimeCosting, IRContext, Evaluation, _} import sigmastate.interpreter.CryptoConstants.EcPointType +import sigmastate.utils.Helpers._ +import sigmastate.helpers.TestingHelpers._ import special.sigma import scala.annotation.tailrec @@ -29,7 +31,8 @@ import scala.language.implicitConversions trait SigmaTestingCommons extends PropSpec with PropertyChecks with GeneratorDrivenPropertyChecks - with Matchers with TestUtils with TestContexts with ValidationSpecification { + with Matchers + with TestUtils with TestContexts with ValidationSpecification { val fakeSelf: ErgoBox = createBox(0, TrueProp) @@ -60,33 +63,6 @@ trait SigmaTestingCommons extends PropSpec tree } - def createBox(value: Long, - proposition: ErgoTree, - additionalTokens: Seq[(Digest32, Long)] = Seq(), - additionalRegisters: Map[NonMandatoryRegisterId, _ <: EvaluatedValue[_ <: SType]] = Map()) - = ErgoBox(value, proposition, 0, additionalTokens, additionalRegisters) - - def createBox(value: Long, - proposition: ErgoTree, - creationHeight: Int) - = ErgoBox(value, proposition, creationHeight, Seq(), Map(), ErgoBox.allZerosModifierId) - - /** - * Create fake transaction with provided outputCandidates, but without inputs and data inputs. - * Normally, this transaction will be invalid as far as it will break rule that sum of - * coins in inputs should not be less then sum of coins in outputs, but we're not checking it - * in our test cases - */ - def createTransaction(outputCandidates: IndexedSeq[ErgoBoxCandidate]): ErgoLikeTransaction = { - new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(), outputCandidates) - } - - def createTransaction(box: ErgoBoxCandidate): ErgoLikeTransaction = createTransaction(IndexedSeq(box)) - - def createTransaction(dataInputs: IndexedSeq[ErgoBox], - outputCandidates: IndexedSeq[ErgoBoxCandidate]): ErgoLikeTransaction = - new ErgoLikeTransaction(IndexedSeq(), dataInputs.map(b => DataInput(b.id)), outputCandidates) - class TestingIRContext extends TestContext with IRContext with CompiletimeCosting { override def onCostingResult[T](env: ScriptEnv, tree: SValue, res: RCostingResultEx[T]): Unit = { env.get(ScriptNameProp) match { @@ -133,9 +109,9 @@ trait SigmaTestingCommons extends PropSpec } case class CompiledFunc[A,B] - (script: String, bindings: Seq[(Byte, EvaluatedValue[_ <: SType])], expr: SValue, func: A => B) - (implicit val tA: RType[A], val tB: RType[B]) extends Function1[A, B] { - override def apply(x: A): B = func(x) + (script: String, bindings: Seq[(Byte, EvaluatedValue[_ <: SType])], expr: SValue, func: A => (B, Int)) + (implicit val tA: RType[A], val tB: RType[B]) extends Function1[A, (B, Int)] { + override def apply(x: A): (B, Int) = func(x) } /** The same operations are executed as part of Interpreter.verify() */ @@ -163,9 +139,7 @@ trait SigmaTestingCommons extends PropSpec import IR._ import IR.Context._; val tA = RType[A] - val tB = RType[B] val tpeA = Evaluation.rtypeToSType(tA) - val tpeB = Evaluation.rtypeToSType(tB) val code = s"""{ | val func = $funcScript @@ -188,7 +162,7 @@ trait SigmaTestingCommons extends PropSpec } // The following is done as part of Interpreter.verify() - val valueFun = { + val (costF, valueFun) = { val costingRes = getCostingResult(env, compiledTree) val calcF = costingRes.calcF val tree = IR.buildTree(calcF) @@ -198,13 +172,14 @@ trait SigmaTestingCommons extends PropSpec val lA = Liftables.asLiftable[SContext, IR.Context](calcF.elem.eDom.liftable) val lB = Liftables.asLiftable[Any, Any](calcF.elem.eRange.liftable) - IR.compile[SContext, Any, IR.Context, Any](IR.getDataEnv, calcF)(lA, lB) + val vf = IR.compile[SContext, Any, IR.Context, Any](IR.getDataEnv, calcF)(lA, lB) + (costingRes.costF, vf) } val f = (in: A) => { implicit val cA = tA.classTag val x = fromPrimView(in) - val sigmaCtx = in match { + val (costingCtx, sigmaCtx) = in match { case ctx: CostingDataContext => // the context is passed as function argument (this is for testing only) // This is to overcome non-functional semantics of context operations @@ -224,15 +199,22 @@ trait SigmaTestingCommons extends PropSpec } else { ctx.vars.updated(1, ctxVar) } - ctx.copy(vars = newVars) + val calcCtx = ctx.copy(vars = newVars) + val costCtx = calcCtx.copy(isCost = true) + (costCtx, calcCtx) case _ => val ergoCtx = ErgoLikeContextTesting.dummy(createBox(0, TrueProp)) .withBindings(1.toByte -> Constant[SType](x.asInstanceOf[SType#WrappedType], tpeA)) .withBindings(bindings: _*) - ergoCtx.toSigmaContext(IR, isCost = false) + val calcCtx = ergoCtx.toSigmaContext(IR, isCost = false).asInstanceOf[CostingDataContext] + val costCtx = calcCtx.copy(isCost = true) + (costCtx, calcCtx) } + + val estimatedCost = IR.checkCostWithContext(costingCtx, costF, ScriptCostLimit.value, 0L).getOrThrow + val (res, _) = valueFun(sigmaCtx) - res.asInstanceOf[B] + (res.asInstanceOf[B], estimatedCost) } val Terms.Apply(funcVal, _) = compiledTree.asInstanceOf[SValue] CompiledFunc(funcScript, bindings.toSeq, funcVal, f) diff --git a/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala b/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala new file mode 100644 index 0000000000..f6dd44919a --- /dev/null +++ b/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala @@ -0,0 +1,76 @@ +package sigmastate.helpers + +import scorex.crypto.hash.Digest32 +import special.collection.Coll +import scorex.util.ModifierId +import org.ergoplatform.{DataInput, ErgoLikeTransaction, ErgoBox, ErgoBoxCandidate} +import sigmastate.Values.ErgoTree +import org.ergoplatform.ErgoBox.{AdditionalRegisters, allZerosModifierId, TokenId} +import sigmastate.eval.CostingSigmaDslBuilder +import sigmastate.eval._ + +// TODO refactor: unification is required between two hierarchies of tests +// and as part of it, more methods can be moved to TestingHelpers + +/** A collection of helper methods which can be used across test suites. */ +object TestingHelpers { + + def testBox(value: Long, + ergoTree: ErgoTree, + creationHeight: Int, + additionalTokens: Seq[(TokenId, Long)] = Nil, + additionalRegisters: AdditionalRegisters = Map.empty, + transactionId: ModifierId = allZerosModifierId, + boxIndex: Short = 0): ErgoBox = + new ErgoBox(value, ergoTree, + CostingSigmaDslBuilder.Colls.fromArray(additionalTokens.toArray[(TokenId, Long)]), + additionalRegisters, + transactionId, boxIndex, creationHeight) + + def createBox(value: Long, + proposition: ErgoTree, + additionalTokens: Seq[(Digest32, Long)] = Seq(), + additionalRegisters: AdditionalRegisters = Map()) + = testBox(value, proposition, 0, additionalTokens, additionalRegisters) + + def createBox(value: Long, + proposition: ErgoTree, + creationHeight: Int) + = testBox(value, proposition, creationHeight, Seq(), Map(), ErgoBox.allZerosModifierId) + + /** Copies the given box allowing also to update fields. */ + def copyBox(box: ErgoBox)( + value: Long = box.value, + ergoTree: ErgoTree = box.ergoTree, + additionalTokens: Coll[(TokenId, Long)] = box.additionalTokens, + additionalRegisters: AdditionalRegisters = box.additionalRegisters, + transactionId: ModifierId = box.transactionId, + index: Short = box.index, + creationHeight: Int = box.creationHeight): ErgoBox = { + new ErgoBox(value, ergoTree, additionalTokens, additionalRegisters, transactionId, index, creationHeight) + } + + /** Creates a new box by updating some of the additional registers with the given new bindings. + * @param newBindings a map of the registers to be updated with new values + */ + def updatedRegisters(box: ErgoBox, newBindings: AdditionalRegisters): ErgoBox = { + copyBox(box)(additionalRegisters = box.additionalRegisters ++ newBindings) + } + + /** + * Create fake transaction with provided outputCandidates, but without inputs and data inputs. + * Normally, this transaction will be invalid as far as it will break rule that sum of + * coins in inputs should not be less then sum of coins in outputs, but we're not checking it + * in our test cases + */ + def createTransaction(outputCandidates: IndexedSeq[ErgoBoxCandidate]): ErgoLikeTransaction = { + new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(), outputCandidates) + } + + def createTransaction(box: ErgoBoxCandidate): ErgoLikeTransaction = createTransaction(IndexedSeq(box)) + + def createTransaction(dataInputs: IndexedSeq[ErgoBox], + outputCandidates: IndexedSeq[ErgoBoxCandidate]): ErgoLikeTransaction = + new ErgoLikeTransaction(IndexedSeq(), dataInputs.map(b => DataInput(b.id)), outputCandidates) + +} diff --git a/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala index d3a687fb67..751df5c0cf 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala @@ -79,6 +79,7 @@ class SigSerializerSpecification extends SigmaTestingCommons with ObjectGenerato boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) + .withCostLimit(Long.MaxValue) // To avoid occasional cost limit exceptions which are irrelevant here try { // get sigma conjectures out of transformers diff --git a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala index e6c80cf30e..6b2593b2b7 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala @@ -14,6 +14,7 @@ import sigmastate.eval.{CSigmaProp, IRContext} import sigmastate.eval._ import sigmastate.eval.Extensions._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ import special.collection.Coll @@ -210,12 +211,12 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => ).asBoolValue.toSigmaProp prop shouldBe propTree - val newBox1 = ErgoBox(10, pubkey, 0) + val newBox1 = testBox(10, pubkey, 0) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = createTransaction(newBoxes) - val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(SigmaDsl.avlTree(treeData)))) + val s = testBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(SigmaDsl.avlTree(treeData)))) val ctx = ErgoLikeContextTesting( currentHeight = 50, @@ -250,13 +251,13 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => |}""".stripMargin).asBoolValue.toSigmaProp val recipientProposition = new ContextEnrichingTestProvingInterpreter().dlogSecrets.head.publicImage - val selfBox = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(SigmaDsl.avlTree(treeData)))) + val selfBox = testBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(SigmaDsl.avlTree(treeData)))) val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), - createTransaction(ErgoBox(1, recipientProposition, 0)), + createTransaction(testBox(1, recipientProposition, 0)), self = selfBox) avlProver.performOneOperation(Lookup(treeElements.head._1)) @@ -314,12 +315,12 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => ).asBoolValue.toSigmaProp prop shouldBe propTree - val newBox1 = ErgoBox(10, pubkey, 0) + val newBox1 = testBox(10, pubkey, 0) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = createTransaction(newBoxes) - val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(treeData), reg2 -> ByteArrayConstant(key))) + val s = testBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(treeData), reg2 -> ByteArrayConstant(key))) val ctx = ErgoLikeContextTesting( currentHeight = 50, @@ -366,12 +367,12 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => | sigmaProp(tree.getMany(keys, proof).forall( { (o: Option[Coll[Byte]]) => o.isDefined })) |}""".stripMargin).asBoolValue.toSigmaProp - val newBox1 = ErgoBox(10, pubkey, 0) + val newBox1 = testBox(10, pubkey, 0) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = ErgoLikeTransaction(IndexedSeq(), newBoxes) - val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(treeData))) + val s = testBox(20, TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(treeData))) val ctx = ErgoLikeContextTesting( currentHeight = 50, diff --git a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index d3253f26f1..02929e5a3d 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -10,6 +10,7 @@ import sigmastate.Values._ import sigmastate._ import sigmastate.eval.Extensions._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ import special.sigma.InvalidType @@ -68,12 +69,12 @@ class BasicOpsSpecification extends SigmaTestingCommons { prop shouldBe propExp val p3 = prover.dlogSecrets(2).publicImage - val boxToSpend = ErgoBox(10, prop, additionalRegisters = Map( + val boxToSpend = testBox(10, prop, additionalRegisters = Map( reg1 -> SigmaPropConstant(p3), reg2 -> IntConstant(1)), creationHeight = 5) - val newBox1 = ErgoBox(10, prop, creationHeight = 0, boxIndex = 0, additionalRegisters = Map( + val newBox1 = testBox(10, prop, creationHeight = 0, boxIndex = 0, additionalRegisters = Map( reg1 -> IntConstant(1), reg2 -> IntConstant(10))) val tx = createTransaction(newBox1) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala index 71f0a06e52..70ebaa4f04 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala @@ -12,6 +12,7 @@ import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util._ import sigmastate.Values.{IntConstant, LongConstant} import sigmastate.helpers.{BlockchainState, ErgoLikeContextTesting, ErgoLikeTestProvingInterpreter, ErgoTransactionValidator, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.ContextExtension import sigmastate.eval._ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} @@ -212,7 +213,7 @@ object BlockchainSimulationSpecification { val initBlock = Block( (0 until windowSize).map { i => val txId = hash.hash(i.toString.getBytes ++ scala.util.Random.nextString(12).getBytes).toModifierId - val boxes = (1 to 30).map(_ => ErgoBox(10, GE(Height, IntConstant(i)).toSigmaProp, 0, Seq(), Map(heightReg -> IntConstant(i)), txId)) + val boxes = (1 to 30).map(_ => testBox(10, GE(Height, IntConstant(i)).toSigmaProp, 0, Seq(), Map(heightReg -> IntConstant(i)), txId)) ergoplatform.ErgoLikeTransaction(IndexedSeq(), boxes) }, ErgoLikeContextTesting.dummyPubkey diff --git a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala index 3eebdd1e28..25980f9f11 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala @@ -5,6 +5,7 @@ import org.ergoplatform.ErgoScriptPredef.TrueProp import sigmastate.Values._ import sigmastate._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.lang.Terms._ import org.ergoplatform._ import sigmastate.SCollection._ @@ -73,8 +74,8 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { val prop = compile(Map(), code).asBoolValue.toSigmaProp expectedComp.foreach(prop shouldBe _) - val ctx = context(boxesToSpendValues.map(ErgoBox(_, pubkey, 0)), - outputBoxValues.map(ErgoBox(_, pubkey, 0))) + val ctx = context(boxesToSpendValues.map(testBox(_, pubkey, 0)), + outputBoxValues.map(testBox(_, pubkey, 0))) (prover, verifier, prop, ctx) } @@ -92,8 +93,8 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { ).toSigmaProp prop shouldBe expProp - val newBox1 = ErgoBox(16, pubkey, 0) - val newBox2 = ErgoBox(15, pubkey, 0) + val newBox1 = testBox(16, pubkey, 0) + val newBox2 = testBox(15, pubkey, 0) val newBoxes = IndexedSeq(newBox1, newBox2) val spendingTransaction = createTransaction(newBoxes) @@ -124,8 +125,8 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { ).toSigmaProp prop shouldBe propTree - val newBox1 = ErgoBox(10, pubkey, 0) - val newBox2 = ErgoBox(10, pubkey, 0) + val newBox1 = testBox(10, pubkey, 0) + val newBox2 = testBox(10, pubkey, 0) val newBoxes = IndexedSeq(newBox1, newBox2) val spendingTransaction = createTransaction(newBoxes) @@ -154,8 +155,8 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { ).toSigmaProp prop shouldBe propTree - val newBox1 = ErgoBox(10, pubkey, 0) - val newBox2 = ErgoBox(11, pubkey, 0) + val newBox1 = testBox(10, pubkey, 0) + val newBox2 = testBox(11, pubkey, 0) val newBoxes = IndexedSeq(newBox1, newBox2) val spendingTransaction = createTransaction(newBoxes) @@ -192,13 +193,13 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { ).toSigmaProp prop shouldBe propTree - val newBox1 = ErgoBox(10, pubkey, 0, Seq(), Map(reg1 -> LongConstant(3))) - val newBox2 = ErgoBox(10, pubkey, 0, Seq(), Map(reg1 -> LongConstant(6))) + val newBox1 = testBox(10, pubkey, 0, Seq(), Map(reg1 -> LongConstant(3))) + val newBox2 = testBox(10, pubkey, 0, Seq(), Map(reg1 -> LongConstant(6))) val newBoxes = IndexedSeq(newBox1, newBox2) val spendingTransaction = createTransaction(newBoxes) - val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> LongConstant(5))) + val s = testBox(20, TrueProp, 0, Seq(), Map(reg1 -> LongConstant(5))) val ctx = ErgoLikeContextTesting( currentHeight = 50, @@ -235,13 +236,13 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { prop shouldBe propTree - val newBox1 = ErgoBox(10, pubkey, 0) - val newBox2 = ErgoBox(10, pubkey, 0, Seq(), Map(reg1 -> LongConstant(6))) + val newBox1 = testBox(10, pubkey, 0) + val newBox2 = testBox(10, pubkey, 0, Seq(), Map(reg1 -> LongConstant(6))) val newBoxes = IndexedSeq(newBox1, newBox2) val spendingTransaction = createTransaction(newBoxes) - val s = ErgoBox(20, TrueProp, 0, Seq(), Map(reg1 -> LongConstant(5))) + val s = testBox(20, TrueProp, 0, Seq(), Map(reg1 -> LongConstant(5))) val ctx = ErgoLikeContextTesting( currentHeight = 50, @@ -266,13 +267,13 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { val propTree = SigmaAnd(pubkey, BoolToSigmaProp(EQ(SizeOf(Outputs), Plus(SizeOf(Inputs), IntConstant(1))))) prop shouldBe propTree - val newBox1 = ErgoBox(11, pubkey, 0) - val newBox2 = ErgoBox(10, pubkey, 0) + val newBox1 = testBox(11, pubkey, 0) + val newBox2 = testBox(10, pubkey, 0) val newBoxes = IndexedSeq(newBox1, newBox2) val spendingTransaction = createTransaction(newBoxes) - val s = ErgoBox(21, pubkey, 0) + val s = testBox(21, pubkey, 0) val ctx = ErgoLikeContextTesting( currentHeight = 50, diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala index 99533b2521..da779b4668 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala @@ -15,8 +15,8 @@ import sigmastate.interpreter.Interpreter._ import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.ProveDHTuple import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTransactionTesting, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.lang.Terms._ -import sigmastate.lang.exceptions.InterpreterException import sigmastate.serialization.{SerializationSpecification, ValueSerializer} import sigmastate.utils.Helpers._ @@ -239,8 +239,8 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons ) prop shouldBe propExp - val newBox1 = ErgoBox(11, pubkey, 0) - val newBox2 = ErgoBox(10, pubkey, 0) + val newBox1 = testBox(11, pubkey, 0) + val newBox2 = testBox(10, pubkey, 0) val newBoxes = IndexedSeq(newBox1, newBox2) val spendingTransaction = createTransaction(newBoxes) @@ -269,8 +269,8 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val prop = SigmaAnd(pubkey, BoolToSigmaProp(GT(ExtractAmount(ByIndex(Outputs, 0)), LongConstant(10)))) compiledProp shouldBe prop - val newBox1 = ErgoBox(11, pubkey, 0) - val newBox2 = ErgoBox(10, pubkey, 0) + val newBox1 = testBox(11, pubkey, 0) + val newBox2 = testBox(10, pubkey, 0) val newBoxes = IndexedSeq(newBox1, newBox2) val spendingTransaction = createTransaction(newBoxes) @@ -310,13 +310,13 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val prop = SigmaAnd(hashEquals, scriptIsCorrect) val recipientProposition = SigmaPropConstant(new ContextEnrichingTestProvingInterpreter().dlogSecrets.head.publicImage) - val selfBox = ErgoBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map()) + val selfBox = testBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map()) val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), - createTransaction(ErgoBox(1, recipientProposition, 0)), + createTransaction(testBox(1, recipientProposition, 0)), self = selfBox) val proof = prover.prove(prop, ctx, fakeMessage).get @@ -347,11 +347,11 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons CreateProveDlog(ExtractRegisterAs[SGroupElement.type](Self, regPubkey2).get)) prop shouldBe propTree - val newBox1 = ErgoBox(10, pubkey3, 0) + val newBox1 = testBox(10, pubkey3, 0) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = createTransaction(newBoxes) - val s1 = ErgoBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), + val s1 = testBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map(regPubkey1 -> GroupElementConstant(pubkey1.value), regPubkey2 -> GroupElementConstant(pubkey2.value))) @@ -368,7 +368,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons //make sure that wrong case couldn't be proved - val s2 = ErgoBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), + val s2 = testBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map(regPubkey1 -> GroupElementConstant(pubkey1.value))) val wrongCtx = ErgoLikeContextTesting( currentHeight = 50, @@ -404,13 +404,13 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val prop = SigmaAnd(hashEquals.toSigmaProp, scriptIsCorrect) val recipientProposition = new ContextEnrichingTestProvingInterpreter().dlogSecrets.head.publicImage - val selfBox = ErgoBox(20, TrueProp, 0, Seq(), Map()) + val selfBox = testBox(20, TrueProp, 0, Seq(), Map()) val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), - createTransaction(ErgoBox(1, recipientProposition, 0)), + createTransaction(testBox(1, recipientProposition, 0)), self = selfBox) val proof = prover.prove(prop, ctx, fakeMessage).get @@ -430,10 +430,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val pubkey1 = prover.dlogSecrets.head.publicImage val pubkey2 = prover.dlogSecrets(1).publicImage - val brother = ErgoBox(10, pubkey1, 0) - val brotherWithWrongId = ErgoBox(10, pubkey1, 0, boxIndex = 120: Short) + val brother = testBox(10, pubkey1, 0) + val brotherWithWrongId = testBox(10, pubkey1, 0, boxIndex = 120: Short) - val newBox = ErgoBox(20, pubkey2, 0) + val newBox = testBox(20, pubkey2, 0) val newBoxes = IndexedSeq(newBox) val spendingTransaction = createTransaction(newBoxes) @@ -456,7 +456,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val altProp = compile(altEnv, """INPUTS.size == 2 && INPUTS(0).id == friend.id""").asBoolValue.toSigmaProp altProp shouldBe prop - val s = ErgoBox(10, prop, 0, Seq(), Map()) + val s = testBox(10, prop, 0, Seq(), Map()) val ctx = ErgoLikeContextTesting( currentHeight = 50, @@ -504,10 +504,10 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val pubkey1 = prover.dlogSecrets.head.publicImage val pubkey2 = prover.dlogSecrets(1).publicImage - val friend = ErgoBox(10, pubkey1, 0) - val friendWithWrongId = ErgoBox(10, pubkey1, 0, boxIndex = 120: Short) + val friend = testBox(10, pubkey1, 0) + val friendWithWrongId = testBox(10, pubkey1, 0, boxIndex = 120: Short) - val newBox = ErgoBox(20, pubkey2, 0) + val newBox = testBox(20, pubkey2, 0) val newBoxes = IndexedSeq(newBox) val spendingTransaction = createTransaction(newBoxes) @@ -536,7 +536,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val altProp = compile(env, "INPUTS.exists ({ (inputBox: Box) => inputBox.id == friend.id })").asBoolValue.toSigmaProp altProp shouldBe prop - val s = ErgoBox(10, prop, 0, Seq(), Map()) + val s = testBox(10, prop, 0, Seq(), Map()) val ctx1 = ErgoLikeContextTesting( currentHeight = 50, @@ -604,12 +604,12 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons ExtractRegisterAs[SByteArray](ByIndex(Inputs, 1), reg1).get))).toSigmaProp prop shouldBe propExpected - val input0 = ErgoBox(10, pubkey, 0, Seq(), Map()) - val input1 = ErgoBox(1, pubkey, 0, Seq(), Map(reg1 -> ByteArrayConstant(preimageHello))) - val input2 = ErgoBox(1, pubkey, 0, Seq(), Map(reg1 -> ByteArrayConstant(preimageWrong))) - val input3 = ErgoBox(10, prop, 0, Seq(), Map()) + val input0 = testBox(10, pubkey, 0, Seq(), Map()) + val input1 = testBox(1, pubkey, 0, Seq(), Map(reg1 -> ByteArrayConstant(preimageHello))) + val input2 = testBox(1, pubkey, 0, Seq(), Map(reg1 -> ByteArrayConstant(preimageWrong))) + val input3 = testBox(10, prop, 0, Seq(), Map()) - val output = ErgoBox(22, pubkey, 0, Seq(), Map()) + val output = testBox(22, pubkey, 0, Seq(), Map()) val spendingTransaction = createTransaction(output) @@ -633,7 +633,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val sigmaProp = SigmaPropConstant(prover.dlogSecrets.head.publicImage) // put SigmaProp into the register val regValue = ByteArrayConstant(ValueSerializer.serialize(sigmaProp)) - val box = ErgoBox(20, TrueProp, 0, Seq(), Map(R4 -> regValue)) + val box = testBox(20, TrueProp, 0, Seq(), Map(R4 -> regValue)) // expect SBoolean in the register val prop = DeserializeRegister(R4, SBoolean).toSigmaProp @@ -643,7 +643,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(box), - createTransaction(IndexedSeq(ErgoBox(10, TrueProp, 0))), + createTransaction(IndexedSeq(testBox(10, TrueProp, 0))), self = box) an[RuntimeException] should be thrownBy @@ -662,13 +662,13 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons DeserializeContext(scriptId, scriptProp.tpe) ).toSigmaProp - val box = ErgoBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map()) + val box = testBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map()) val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(box), - createTransaction(IndexedSeq(ErgoBox(10, TrueProp, 0))), + createTransaction(IndexedSeq(testBox(10, TrueProp, 0))), self = box) val pr = prover.prove(prop, ctx, fakeMessage).get diff --git a/sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala b/sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala index c24a80983a..26f1948312 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/benchmarks/CrowdfundingBenchmark.scala @@ -1,19 +1,20 @@ package sigmastate.utxo.benchmarks -import org.ergoplatform.{ErgoBox, ErgoLikeContext, ErgoLikeTransaction, ErgoScriptPredef} +import org.ergoplatform.{ErgoLikeContext, ErgoScriptPredef} import sigmastate.Values._ import sigmastate._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import scalan.util.BenchmarkUtil._ class CrowdfundingBenchmark extends SigmaTestingCommons { implicit lazy val IR = new TestingIRContext def createTestContext(contract: CrowdFundingContract): ErgoLikeContext = { - val outputToSpend = ErgoBox(10, ErgoScriptPredef.TrueProp, 0) + val outputToSpend = testBox(10, ErgoScriptPredef.TrueProp, 0) //First case: height < timeout, project is able to claim amount of tokens not less than required threshold - val tx1Output1 = ErgoBox(contract.minToRaise, contract.projectPubKey, 0) - val tx1Output2 = ErgoBox(1, contract.projectPubKey, 0) + val tx1Output1 = testBox(contract.minToRaise, contract.projectPubKey, 0) + val tx1Output2 = testBox(1, contract.projectPubKey, 0) //normally this transaction would invalid, but we're not checking it in this test val tx = createTransaction(IndexedSeq(tx1Output1, tx1Output2)) val ctx = ErgoLikeContextTesting( diff --git a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala index 7f19aaa06c..4612112f85 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala @@ -5,10 +5,11 @@ import org.ergoplatform._ import scorex.crypto.authds.{ADDigest, ADKey, ADValue} import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Remove} import scorex.crypto.hash.{Blake2b256, Digest32} -import sigmastate.{AvlTreeData, AvlTreeFlags, GE, Values} +import sigmastate.{AvlTreeData, AvlTreeFlags, Values} import sigmastate.Values.{ErgoTree, LongConstant} import sigmastate.eval._ import sigmastate.helpers.{BlockchainState, ErgoLikeContextTesting, ErgoLikeTestProvingInterpreter, ErgoTransactionValidator, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.utils.Helpers._ import scala.collection.mutable import scala.util.{Random, Try} @@ -147,7 +148,7 @@ object BlockchainSimulationTestingCommons extends SigmaTestingCommons { val initBlock = FullBlock( (0 until 10).map { i => val txId = Blake2b256.hash(i.toString.getBytes ++ scala.util.Random.nextString(12).getBytes).toModifierId - val boxes = (1 to 50).map(_ => ErgoBox(10, Values.TrueLeaf.toSigmaProp, i, Seq(), Map(), txId)) + val boxes = (1 to 50).map(_ => testBox(10, Values.TrueLeaf.toSigmaProp, i, Seq(), Map(), txId)) createTransaction(boxes) }, ErgoLikeContextTesting.dummyPubkey diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala index cd7a743cda..31251cbb93 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala @@ -4,6 +4,7 @@ import org.ergoplatform._ import scorex.util.ScorexLogging import sigmastate.Values.IntConstant import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.ContextExtension import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.lang.Terms._ @@ -135,7 +136,7 @@ block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661 val minerPubkey = minerImage.pkBytes val minerProp = minerImage - val initialBoxCandidate: ErgoBox = ErgoBox(coinsTotal / 4, prop, 0, Seq(), Map(register -> IntConstant(-1))) + val initialBoxCandidate: ErgoBox = testBox(coinsTotal / 4, prop, 0, Seq(), Map(register -> IntConstant(-1))) val initBlock = FullBlock(IndexedSeq(createTransaction(initialBoxCandidate)), minerPubkey) val genesisState = ValidationState.initialState(initBlock) val fromState = genesisState.boxesReader.byId(genesisState.boxesReader.allIds.head).get diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala index 1933f73c0d..fa03a9904d 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala @@ -5,6 +5,7 @@ import org.ergoplatform._ import sigmastate.AvlTreeData import sigmastate.Values.{IntConstant, LongConstant} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ @@ -96,7 +97,7 @@ class ColdWalletAdvContractExampleSpecification extends SigmaTestingCommons { val avbl1Key = depositAmount * percent1Key/100 val avbl2Key = depositAmount * percent2Key/100 - val depositOutput = ErgoBox(depositAmount, address.script, depositHeight, Nil, + val depositOutput = testBox(depositAmount, address.script, depositHeight, Nil, Map( R4 -> IntConstant(depositHeight), // can keep value in R4 initially R5 -> LongConstant(avbl1Key), // keeping it below min will make UTXO unspendable @@ -115,14 +116,14 @@ class ColdWalletAdvContractExampleSpecification extends SigmaTestingCommons { val firstWithdrawAmount1Key = depositAmount * percent1Key / 100 // less than or equal to percent val firstChangeAmount1Key = depositAmount - firstWithdrawAmount1Key - val firstChangeOutput1Key = ErgoBox(firstChangeAmount1Key, address.script, firstWithdrawHeight, Nil, + val firstChangeOutput1Key = testBox(firstChangeAmount1Key, address.script, firstWithdrawHeight, Nil, Map( R4 -> IntConstant(depositHeight), // newStart (= old start) R5 -> LongConstant(avbl1Key - firstWithdrawAmount1Key), // new avbl1Key (= 0) R6 -> LongConstant(avbl2Key) // new avbl2Key (= old avbl2Key) ) ) - val firstWithdrawOutput1Key = ErgoBox(firstWithdrawAmount1Key, carolPubKey, firstWithdrawHeight) + val firstWithdrawOutput1Key = testBox(firstWithdrawAmount1Key, carolPubKey, firstWithdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val firstWithdrawTx1Key = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(firstChangeOutput1Key, firstWithdrawOutput1Key)) @@ -151,14 +152,14 @@ class ColdWalletAdvContractExampleSpecification extends SigmaTestingCommons { val firstWithdrawAmount2Key = depositAmount * percent2Key / 100 // less than or equal to percent val firstChangeAmount2Key = depositAmount - firstWithdrawAmount2Key - val firstChangeOutput2Key = ErgoBox(firstChangeAmount2Key, address.script, firstWithdrawHeight, Nil, + val firstChangeOutput2Key = testBox(firstChangeAmount2Key, address.script, firstWithdrawHeight, Nil, Map( R4 -> IntConstant(depositHeight), // newStart (= old start) R5 -> LongConstant(avbl1Key), // new avbl1Key (= 0) R6 -> LongConstant(avbl2Key - firstWithdrawAmount2Key) // new avbl2Key (= old avbl2Key) ) ) - val firstWithdrawOutput2Key = ErgoBox(firstWithdrawAmount2Key, carolPubKey, firstWithdrawHeight) + val firstWithdrawOutput2Key = testBox(firstWithdrawAmount2Key, carolPubKey, firstWithdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val firstWithdrawTx2Key = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(firstChangeOutput2Key, firstWithdrawOutput2Key)) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala index 64b0bf4b1c..3987f84dfd 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala @@ -3,6 +3,7 @@ package sigmastate.utxo.examples import org.ergoplatform.ErgoBox.{R4, R5} import org.ergoplatform._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.AvlTreeData import sigmastate.Values.{IntConstant, LongConstant} import sigmastate.interpreter.Interpreter.ScriptNameProp @@ -72,7 +73,7 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { val depositHeight = 50 val min = depositAmount - depositAmount * percent/100 // should be 99000 (99k) - val depositOutput = ErgoBox(depositAmount, address.script, depositHeight, Nil, + val depositOutput = testBox(depositAmount, address.script, depositHeight, Nil, Map( R4 -> IntConstant(depositHeight), // can keep any value in R4 initially R5 -> LongConstant(min) // keeping it below min will make UTXO unspendable @@ -89,7 +90,7 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { // Both Alice ane Bob withdraw val withdrawAmountFull = depositAmount // full amount is withdrawn - val withdrawOutputAliceAndBob = ErgoBox(withdrawAmountFull, carolPubKey, firstWithdrawHeight) + val withdrawOutputAliceAndBob = testBox(withdrawAmountFull, carolPubKey, firstWithdrawHeight) val withdrawTxAliceAndBob = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(withdrawOutputAliceAndBob)) @@ -112,13 +113,13 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { val firstWithdrawAmount = depositAmount * percent / 100 // less than or eqaul to percent (1000) val firstChangeAmount = depositAmount - firstWithdrawAmount // 99000 - val firstChangeOutput = ErgoBox(firstChangeAmount, address.script, firstWithdrawHeight, Nil, + val firstChangeOutput = testBox(firstChangeAmount, address.script, firstWithdrawHeight, Nil, Map( R4 -> IntConstant(depositHeight), // newStart (= old start) = 50 R5 -> LongConstant(min) // newMin (= old min) = 99000 ) ) - val firstWithdrawOutput = ErgoBox(firstWithdrawAmount, carolPubKey, firstWithdrawHeight) + val firstWithdrawOutput = testBox(firstWithdrawAmount, carolPubKey, firstWithdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val firstWithdrawTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(firstChangeOutput, firstWithdrawOutput)) @@ -141,13 +142,13 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { // invalid (amount greater than allowed) val withdrawAmountInvalid = depositAmount * percent / 100 + 1 // more than percent val changeAmountInvalid = depositAmount - withdrawAmountInvalid - val changeOutputInvalid = ErgoBox(changeAmountInvalid, address.script, firstWithdrawHeight, Nil, + val changeOutputInvalid = testBox(changeAmountInvalid, address.script, firstWithdrawHeight, Nil, Map( R4 -> IntConstant(depositHeight), // newStart (= old start) R5 -> LongConstant(min) // newMin (= old min) ) ) - val withdrawOutputInvalid = ErgoBox(withdrawAmountInvalid, carolPubKey, firstWithdrawHeight) + val withdrawOutputInvalid = testBox(withdrawAmountInvalid, carolPubKey, firstWithdrawHeight) // normally this transaction would be invalid, but we're not checking it in this test val withdrawTxInvalid = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(changeOutputInvalid, withdrawOutputInvalid)) @@ -175,13 +176,13 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { val secondChangeAmount = firstChangeAmount - secondWithdrawAmount val secondMin = firstChangeAmount - firstChangeAmount * percent/100 - val secondChangeOutput = ErgoBox(secondChangeAmount, address.script, secondWithdrawHeight, Nil, + val secondChangeOutput = testBox(secondChangeAmount, address.script, secondWithdrawHeight, Nil, Map( R4 -> IntConstant(secondWithdrawHeight), // newStart R5 -> LongConstant(secondMin) // newMin ) ) - val secondWithdrawOutput = ErgoBox(secondWithdrawAmount, carolPubKey, secondWithdrawHeight) + val secondWithdrawOutput = testBox(secondWithdrawAmount, carolPubKey, secondWithdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val secondWithdrawTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(secondChangeOutput, secondWithdrawOutput)) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala index dbcbe0573e..c44e5acb35 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala @@ -7,6 +7,7 @@ import sigmastate.basics.DLogProtocol.ProveDlog import scorex.crypto.hash.Blake2b256 import sigmastate.Values.{ByteArrayConstant, SigmaPropValue, BooleanConstant} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.TestingHelpers._ import sigmastate.lang.Terms._ import sigmastate.AvlTreeData @@ -127,11 +128,11 @@ class CoopExampleSpecification extends SigmaTestingCommons { """.stripMargin).asSigmaProp { - val self = ErgoBox(totalValue, spendingProp1, 0) - val output1 = ErgoBox(totalValue / 4, pubkeyA, 0) - val output2 = ErgoBox(totalValue / 4, pubkeyB, 0) - val output3 = ErgoBox(totalValue / 4, pubkeyC, 0) - val output4 = ErgoBox(totalValue / 4, pubkeyD, 0) + val self = testBox(totalValue, spendingProp1, 0) + val output1 = testBox(totalValue / 4, pubkeyA, 0) + val output2 = testBox(totalValue / 4, pubkeyB, 0) + val output3 = testBox(totalValue / 4, pubkeyC, 0) + val output4 = testBox(totalValue / 4, pubkeyD, 0) val tx = mkTxFromOutputs(output1, output2, output3, output4) val ctx = mkCtx(5001, tx, self) successProofTest(spendingProp1, ctx, coopA, verifier) @@ -167,11 +168,11 @@ class CoopExampleSpecification extends SigmaTestingCommons { * Withdraw successfully */ { - val self = ErgoBox(totalValue, spendingProp2, 0) - val output1 = ErgoBox(totalValue / 4, pubkeyA, 0) - val output2 = ErgoBox(totalValue / 4, pubkeyB, 0) - val output3 = ErgoBox(totalValue / 4, pubkeyC, 0) - val output4 = ErgoBox(totalValue / 4, pubkeyD, 0) + val self = testBox(totalValue, spendingProp2, 0) + val output1 = testBox(totalValue / 4, pubkeyA, 0) + val output2 = testBox(totalValue / 4, pubkeyB, 0) + val output3 = testBox(totalValue / 4, pubkeyC, 0) + val output4 = testBox(totalValue / 4, pubkeyD, 0) val tx = mkTxFromOutputs(output1, output2, output3, output4) val ctx = mkCtx(5001, tx, self) successProofTest(spendingProp2, ctx, coopA, verifier) @@ -181,9 +182,9 @@ class CoopExampleSpecification extends SigmaTestingCommons { * Won't spend more then defined share */ { - val self = ErgoBox(totalValue, spendingProp2, 0) - val output1 = ErgoBox(totalValue / 2, pubkeyB, 0) - val output2 = ErgoBox(totalValue / 2, pubkeyC, 0) + val self = testBox(totalValue, spendingProp2, 0) + val output1 = testBox(totalValue / 2, pubkeyB, 0) + val output2 = testBox(totalValue / 2, pubkeyC, 0) val tx = mkTxFromOutputs(output1, output2) val ctx = mkCtx(5001, tx, self = self) failingProofTest(spendingProp2, ctx, coopA) @@ -193,11 +194,11 @@ class CoopExampleSpecification extends SigmaTestingCommons { * Won't spend before minimal height */ { - val self = ErgoBox(totalValue, spendingProp2, 0) - val output1 = ErgoBox(totalValue / 4, pubkeyA, 0) - val output2 = ErgoBox(totalValue / 4, pubkeyB, 0) - val output3 = ErgoBox(totalValue / 4, pubkeyC, 0) - val output4 = ErgoBox(totalValue / 4, pubkeyD, 0) + val self = testBox(totalValue, spendingProp2, 0) + val output1 = testBox(totalValue / 4, pubkeyA, 0) + val output2 = testBox(totalValue / 4, pubkeyB, 0) + val output3 = testBox(totalValue / 4, pubkeyC, 0) + val output4 = testBox(totalValue / 4, pubkeyD, 0) val tx = mkTxFromOutputs(output1, output2, output3, output4) val ctx = mkCtx(5000, tx, self) failingProofTest(spendingProp2, ctx, coopA) @@ -220,11 +221,11 @@ class CoopExampleSpecification extends SigmaTestingCommons { * Will spend correctly if all the conditions are satisfied */ { - val self = ErgoBox(totalValue, spendingProp3, 0) - val output1 = ErgoBox(totalValue / 4, pubkeyA, 0) - val output2 = ErgoBox(totalValue / 4, pubkeyB, 0) - val output3 = ErgoBox(totalValue / 4, pubkeyC, 0) - val output4 = ErgoBox(totalValue / 4, pubkeyD, 0) + val self = testBox(totalValue, spendingProp3, 0) + val output1 = testBox(totalValue / 4, pubkeyA, 0) + val output2 = testBox(totalValue / 4, pubkeyB, 0) + val output3 = testBox(totalValue / 4, pubkeyC, 0) + val output4 = testBox(totalValue / 4, pubkeyD, 0) val tx = mkTxFromOutputs(output1, output2, output3, output4) val ctx = mkCtx(5001, tx, self) successProofTest(spendingProp2, ctx, coopA, verifier) @@ -258,11 +259,11 @@ class CoopExampleSpecification extends SigmaTestingCommons { """.stripMargin).asSigmaProp { - val self = ErgoBox(totalValue, spendingProp4, 0) - val output1 = ErgoBox(totalValue / 4, pubkeyA, 0) - val output2 = ErgoBox(totalValue / 4, pubkeyB, 0) - val output3 = ErgoBox(totalValue / 4, pubkeyC, 0) - val output4 = ErgoBox(totalValue / 4, pubkeyD, 0) + val self = testBox(totalValue, spendingProp4, 0) + val output1 = testBox(totalValue / 4, pubkeyA, 0) + val output2 = testBox(totalValue / 4, pubkeyB, 0) + val output3 = testBox(totalValue / 4, pubkeyC, 0) + val output4 = testBox(totalValue / 4, pubkeyD, 0) val tx = mkTxFromOutputs(output1, output2, output3, output4) val ctx = mkCtx(5001, tx, self) successProofTest(spendingProp4, ctx, coopA, verifier) @@ -271,8 +272,8 @@ class CoopExampleSpecification extends SigmaTestingCommons { val spendingProp5 = compile(spendingEnv, "businessKey").asSigmaProp { - val self = ErgoBox(totalValue, spendingProp5, 0) - val output = ErgoBox(totalValue, businessKey, 0) + val self = testBox(totalValue, spendingProp5, 0) + val output = testBox(totalValue, businessKey, 0) val tx = mkTxFromOutputs(output) val ctx = mkCtx(1, tx, self) failingProofTest(spendingProp5, ctx, coopA) @@ -311,12 +312,12 @@ class CoopExampleSpecification extends SigmaTestingCommons { * Check votingSuccess && properSpending case */ { - val self = ErgoBox(totalValue + 1L, thresholdProp, 0) - val output1 = ErgoBox(toolValue, spendingProp1, 0) - val output2 = ErgoBox(constructionValue, spendingProp3, 0) - val output3 = ErgoBox(totalValue - toolValue - constructionValue, spendingProp5, 0) + val self = testBox(totalValue + 1L, thresholdProp, 0) + val output1 = testBox(toolValue, spendingProp1, 0) + val output2 = testBox(constructionValue, spendingProp3, 0) + val output3 = testBox(totalValue - toolValue - constructionValue, spendingProp5, 0) //hack for avoiding None.get exception. - val dummy = ErgoBox(0L, ErgoScriptPredef.TrueProp, 0) + val dummy = testBox(0L, ErgoScriptPredef.TrueProp, 0) val tx = mkTxFromOutputs(output1, output2, output3, dummy) val ctx = mkCtx(2000, tx, self) @@ -331,11 +332,11 @@ class CoopExampleSpecification extends SigmaTestingCommons { * Check withdraw success */ { - val self = ErgoBox(totalValue + 1L, thresholdProp, 0) - val output0 = ErgoBox(totalValue / 4, pubkeyA, 0) - val output1 = ErgoBox(totalValue / 4, pubkeyB, 0) - val output2 = ErgoBox(totalValue / 4, pubkeyC, 0) - val output3 = ErgoBox(totalValue / 4, pubkeyD, 0) + val self = testBox(totalValue + 1L, thresholdProp, 0) + val output0 = testBox(totalValue / 4, pubkeyA, 0) + val output1 = testBox(totalValue / 4, pubkeyB, 0) + val output2 = testBox(totalValue / 4, pubkeyC, 0) + val output3 = testBox(totalValue / 4, pubkeyD, 0) val tx = mkTxFromOutputs(output0, output1, output2, output3) val ctx = mkCtx(2000, tx, self) successProofTest(thresholdProp, ctx, business, verifier) @@ -345,11 +346,11 @@ class CoopExampleSpecification extends SigmaTestingCommons { * Check withdraw failure. Not enough height case. */ { - val self = ErgoBox(totalValue + 1L, thresholdProp, 0) - val output0 = ErgoBox(totalValue / 4, pubkeyA, 0) - val output1 = ErgoBox(totalValue / 4, pubkeyB, 0) - val output2 = ErgoBox(totalValue / 4, pubkeyC, 0) - val output3 = ErgoBox(totalValue / 4, pubkeyD, 0) + val self = testBox(totalValue + 1L, thresholdProp, 0) + val output0 = testBox(totalValue / 4, pubkeyA, 0) + val output1 = testBox(totalValue / 4, pubkeyB, 0) + val output2 = testBox(totalValue / 4, pubkeyC, 0) + val output3 = testBox(totalValue / 4, pubkeyD, 0) val tx = mkTxFromOutputs(output0, output1, output2, output3) val ctx = mkCtx(1000, tx, self) failingProofTest(thresholdProp, ctx, business) @@ -370,8 +371,8 @@ class CoopExampleSpecification extends SigmaTestingCommons { * height not higher, total value is equal */ { - val self = ErgoBox(totalValue, inputProp, 0) - val output = ErgoBox(totalValue, thresholdProp, 0) + val self = testBox(totalValue, inputProp, 0) + val output = testBox(totalValue, thresholdProp, 0) val tx = mkTxFromOutputs(output) val ctx = mkCtx(1000, tx, self) successProofTest(inputProp, ctx, coopA, verifier) @@ -381,8 +382,8 @@ class CoopExampleSpecification extends SigmaTestingCommons { * total value is lower, height is higher */ { - val self = ErgoBox(totalValue - 1L, inputProp, 0) - val output = ErgoBox(totalValue - 1L, thresholdProp, 0) + val self = testBox(totalValue - 1L, inputProp, 0) + val output = testBox(totalValue - 1L, thresholdProp, 0) val tx = mkTxFromOutputs(output) val ctx = mkCtx(1001, tx, self) successProofTest(inputProp, ctx, coopA, verifier) @@ -392,8 +393,8 @@ class CoopExampleSpecification extends SigmaTestingCommons { * negative condition */ { - val self = ErgoBox(totalValue - 1L, inputProp, 0) - val output = ErgoBox(totalValue - 1L, thresholdProp, 0) + val self = testBox(totalValue - 1L, inputProp, 0) + val output = testBox(totalValue - 1L, thresholdProp, 0) val tx = mkTxFromOutputs(output) val ctx = mkCtx(1000, tx, self) failingProofTest(inputProp, ctx, coopA) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala index 3a44b051bf..7d6382ad34 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala @@ -4,16 +4,15 @@ package sigmastate.utxo.examples import java.math.BigInteger import org.ergoplatform.ErgoBox.{R4, R5} -import org.ergoplatform.{ErgoBox, ErgoLikeContext, ErgoLikeTransaction} import sigmastate.AvlTreeData import sigmastate.Values.GroupElementConstant import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.{DiffieHellmanTupleProverInput, ProveDHTuple} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.CryptoConstants import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ -import sigmastate.eval._ class DHTupleExampleSpecification extends SigmaTestingCommons { private implicit lazy val IR = new TestingIRContext @@ -53,7 +52,7 @@ class DHTupleExampleSpecification extends SigmaTestingCommons { |}""".stripMargin ).asSigmaProp - val inBox = ErgoBox(10, script, 50) + val inBox = testBox(10, script, 50) // a blockchain node verifying a block containing a spending transaction val verifier = new ErgoLikeTestInterpreter @@ -70,7 +69,7 @@ class DHTupleExampleSpecification extends SigmaTestingCommons { val carol = new ContextEnrichingTestProvingInterpreter val carolPubKey:ProveDlog = carol.dlogSecrets.head.publicImage - val outBox = ErgoBox(10, carolPubKey, 70, Nil, + val outBox = testBox(10, carolPubKey, 70, Nil, Map( R4 -> g_y, R5 -> g_xy diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala index 65befc4e8b..f8f7edd717 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala @@ -5,6 +5,7 @@ import org.ergoplatform._ import sigmastate.Values.ShortConstant import sigmastate._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.ContextExtension import sigmastate.lang.Terms._ diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala index 1a2ddc93c1..d24fe63bed 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala @@ -11,6 +11,7 @@ import sigmastate._ import sigmastate.eval._ import sigmastate.lang.Terms._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.serialization.ValueSerializer import sigmastate.utxo._ @@ -133,11 +134,11 @@ class FsmExampleSpecification extends SigmaTestingCommons { //creating a box in an initial state - val fsmBox1 = ErgoBox(100, fsmScript, 0, Seq(), Map(fsmDescRegister -> AvlTreeConstant(treeData), + val fsmBox1 = testBox(100, fsmScript, 0, Seq(), Map(fsmDescRegister -> AvlTreeConstant(treeData), currentStateRegister -> ByteConstant(state1Id))) //successful transition from state1 to state2 - val fsmBox2 = ErgoBox(100, fsmScript, 0, Seq(), Map(fsmDescRegister -> AvlTreeConstant(treeData), + val fsmBox2 = testBox(100, fsmScript, 0, Seq(), Map(fsmDescRegister -> AvlTreeConstant(treeData), currentStateRegister -> ByteConstant(state2Id))) avlProver.performOneOperation(Lookup(ADKey @@ (transition12 ++ script1Hash))) @@ -181,7 +182,7 @@ class FsmExampleSpecification extends SigmaTestingCommons { //Box for state3 - val fsmBox3 = ErgoBox(100, fsmScript, 0, Seq(), Map(fsmDescRegister -> AvlTreeConstant(treeData), + val fsmBox3 = testBox(100, fsmScript, 0, Seq(), Map(fsmDescRegister -> AvlTreeConstant(treeData), currentStateRegister -> ByteConstant(state3Id))) //transition from state1 to state3 is impossible @@ -235,7 +236,7 @@ class FsmExampleSpecification extends SigmaTestingCommons { //clearing FSM out of the box in the final state - val freeBox = ErgoBox(100, ErgoScriptPredef.TrueProp, 0) + val freeBox = testBox(100, ErgoScriptPredef.TrueProp, 0) avlProver.performOneOperation(Lookup(ADKey @@ (transition30 ++ script4Hash))) val transition30Proof = avlProver.generateProof() diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala index 429f754b39..b38726f016 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala @@ -11,6 +11,7 @@ import sigmastate.Values.{AvlTreeConstant, IntArrayConstant, CollectionConstant, import sigmastate._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} import sigmastate.helpers.ErgoLikeContextTesting +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ import sigmastate.serialization.ErgoTreeSerializer @@ -380,13 +381,13 @@ class IcoExample extends SigmaTestingCommons { suite => val digest = avlProver.digest val initTreeData = SigmaDsl.avlTree(new AvlTreeData(digest, AvlTreeFlags.AllOperationsAllowed, 32, None)) - val projectBoxBefore = ErgoBox(10, fundingScript, 0, Seq(), + val projectBoxBefore = testBox(10, fundingScript, 0, Seq(), Map(R4 -> ByteArrayConstant(Array.fill(1)(0: Byte)), R5 -> AvlTreeConstant(initTreeData))) val funderBoxCount = 2000 val funderBoxes = (1 to funderBoxCount).map { _ => - ErgoBox(10, Values.TrueLeaf.asSigmaProp, 0, Seq(), + testBox(10, Values.TrueLeaf.asSigmaProp, 0, Seq(), Map(R4 -> ByteArrayConstant(Array.fill(32)(Random.nextInt(Byte.MaxValue).toByte)))) } @@ -401,9 +402,9 @@ class IcoExample extends SigmaTestingCommons { suite => val proof = avlProver.generateProof() val endTree = SigmaDsl.avlTree(new AvlTreeData(avlProver.digest, AvlTreeFlags.AllOperationsAllowed, 32, None)) - val projectBoxAfter = ErgoBox(funderBoxCount * 10 - 1, fundingScript, 0, Seq(), + val projectBoxAfter = testBox(funderBoxCount * 10 - 1, fundingScript, 0, Seq(), Map(R4 -> ByteArrayConstant(Array.fill(1)(0: Byte)), R5 -> AvlTreeConstant(endTree))) - val feeBox = ErgoBox(1, feeProp, 0, Seq(), Map()) + val feeBox = testBox(1, feeProp, 0, Seq(), Map()) val fundingTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(projectBoxAfter, feeBox)) @@ -430,17 +431,17 @@ class IcoExample extends SigmaTestingCommons { suite => val digest = avlProver.digest val openTreeData = SigmaDsl.avlTree(new AvlTreeData(digest, AvlTreeFlags.AllOperationsAllowed, 32, None)) - val projectBoxBeforeClosing = ErgoBox(10, issuanceScript, 0, Seq(), + val projectBoxBeforeClosing = testBox(10, issuanceScript, 0, Seq(), Map(R4 -> ByteArrayConstant(Array.emptyByteArray), R5 -> AvlTreeConstant(openTreeData))) val tokenId = Digest32 @@ projectBoxBeforeClosing.id val closedTreeData = SigmaDsl.avlTree(new AvlTreeData(digest, AvlTreeFlags.RemoveOnly, 32, None)) - val projectBoxAfterClosing = ErgoBox(1, withdrawalScript, 0, Seq(tokenId -> projectBoxBeforeClosing.value), + val projectBoxAfterClosing = testBox(1, withdrawalScript, 0, Seq(tokenId -> projectBoxBeforeClosing.value), Map(R4 -> ByteArrayConstant(tokenId), R5 -> AvlTreeConstant(closedTreeData))) - val ergoWithdrawalBox = ErgoBox(8, Values.TrueLeaf.asSigmaProp, 0, Seq(), Map()) - val feeBox = ErgoBox(1, feeProp, 0, Seq(), Map()) + val ergoWithdrawalBox = testBox(8, Values.TrueLeaf.asSigmaProp, 0, Seq(), Map()) + val feeBox = testBox(1, feeProp, 0, Seq(), Map()) val issuanceTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(projectBoxAfterClosing, ergoWithdrawalBox, feeBox)) @@ -502,16 +503,16 @@ class IcoExample extends SigmaTestingCommons { suite => } val withdrawBoxes = withdrawalAmounts.map { case (prop, tv) => - ErgoBox(1, DefaultSerializer.deserializeErgoTree(prop), 0, Seq(tokenId -> tv)) + testBox(1, DefaultSerializer.deserializeErgoTree(prop), 0, Seq(tokenId -> tv)) } val totalTokenAmount = withdrawalAmounts.map(_._2).sum + 1 - val projectBoxBefore = ErgoBox(11, withdrawalScript, 0, Seq(tokenId -> totalTokenAmount), + val projectBoxBefore = testBox(11, withdrawalScript, 0, Seq(tokenId -> totalTokenAmount), Map(R4 -> ByteArrayConstant(tokenId), R5 -> AvlTreeConstant(fundersTree))) - val projectBoxAfter = ErgoBox(1, withdrawalScript, 0, Seq(tokenId -> 1), + val projectBoxAfter = testBox(1, withdrawalScript, 0, Seq(tokenId -> 1), Map(R4 -> ByteArrayConstant(tokenId), R5 -> AvlTreeConstant(finalTree))) - val feeBox = ErgoBox(1, feeProp, 0, Seq(), Map()) + val feeBox = testBox(1, feeProp, 0, Seq(), Map()) val outputs = IndexedSeq(projectBoxAfter) ++ withdrawBoxes ++ IndexedSeq(feeBox) val fundingTx = ErgoLikeTransaction(IndexedSeq(), outputs) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala index 3268eabad7..c3af822427 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala @@ -9,6 +9,7 @@ import sigmastate.{AvlTreeData, AvlTreeFlags, TrivialProp} import sigmastate.Values.{AvlTreeConstant, ByteArrayConstant, LongConstant, SigmaPropConstant} import sigmastate.eval.{IRContext, SigmaDsl} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.serialization.ErgoTreeSerializer import sigmastate.lang.Terms._ @@ -283,7 +284,7 @@ class LetsSpecification extends SigmaTestingCommons { val digest = avlProver.digest val initTreeData = new AvlTreeData(digest, AvlTreeFlags.InsertOnly, 32, None) - val projectBoxBefore = ErgoBox(10, managementScript, 0, + val projectBoxBefore = testBox(10, managementScript, 0, Seq(letsTokenId -> 1L), Map(R4 -> AvlTreeConstant(SigmaDsl.avlTree(initTreeData)), R5 -> SigmaPropConstant(TrivialProp.TrueProp))) @@ -294,11 +295,11 @@ class LetsSpecification extends SigmaTestingCommons { val proof = avlProver.generateProof() val endTree = new AvlTreeData(avlProver.digest, AvlTreeFlags.InsertOnly, 32, None) - val projectBoxAfter = ErgoBox(9, managementScript, 0, + val projectBoxAfter = testBox(9, managementScript, 0, Seq(letsTokenId -> 1L), Map(R4 -> AvlTreeConstant(SigmaDsl.avlTree(endTree)), R5 -> SigmaPropConstant(TrivialProp.TrueProp))) - val feeBox = ErgoBox(1, feeProp, 0, Seq(), Map()) - val userBox = ErgoBox(1, exchangeScript, 0, Seq(userTokenId -> 1L), Map(R4 -> LongConstant(0))) + val feeBox = testBox(1, feeProp, 0, Seq(), Map()) + val userBox = testBox(1, exchangeScript, 0, Seq(userTokenId -> 1L), Map(R4 -> LongConstant(0))) val issuanceTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(projectBoxAfter, userBox, feeBox)) @@ -333,19 +334,19 @@ class LetsSpecification extends SigmaTestingCommons { avlProver.performOneOperation(Lookup(ADKey @@ userTokenId1)) val proof = avlProver.generateProof() - val directoryBox = ErgoBox(10, managementScript, 0, + val directoryBox = testBox(10, managementScript, 0, Seq(letsTokenId -> 1L), Map(R4 -> AvlTreeConstant(SigmaDsl.avlTree(initTreeData)), R5 -> SigmaPropConstant(TrivialProp.TrueProp))) val directoryDataInput = DataInput(directoryBox.id) - val userBoxBefore0 = ErgoBox(1, exchangeScript, 0, Seq(userTokenId0 -> 1L), + val userBoxBefore0 = testBox(1, exchangeScript, 0, Seq(userTokenId0 -> 1L), Map(R4 -> LongConstant(0), R5 -> SigmaPropConstant(TrivialProp.TrueProp))) - val userBoxBefore1 = ErgoBox(1, exchangeScript, 0, Seq(userTokenId1 -> 1L), + val userBoxBefore1 = testBox(1, exchangeScript, 0, Seq(userTokenId1 -> 1L), Map(R4 -> LongConstant(0), R5 -> SigmaPropConstant(TrivialProp.TrueProp))) - val userBoxAfter0 = ErgoBox(1, exchangeScript, 0, Seq(userTokenId0 -> 1L), Map(R4 -> LongConstant(-5))) - val userBoxAfter1 = ErgoBox(1, exchangeScript, 0, Seq(userTokenId1 -> 1L), Map(R4 -> LongConstant(5))) + val userBoxAfter0 = testBox(1, exchangeScript, 0, Seq(userTokenId0 -> 1L), Map(R4 -> LongConstant(-5))) + val userBoxAfter1 = testBox(1, exchangeScript, 0, Seq(userTokenId1 -> 1L), Map(R4 -> LongConstant(5))) val issuanceTx = new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(directoryDataInput), IndexedSeq(userBoxAfter0, userBoxAfter1)) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala index b705017af3..a66e50993c 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala @@ -8,6 +8,7 @@ import sigmastate.SCollection.SByteArray import sigmastate.Values._ import sigmastate._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.lang.Terms._ import sigmastate.interpreter.Interpreter._ import sigmastate.serialization.ValueSerializer @@ -45,9 +46,9 @@ class MASTExampleSpecification extends SigmaTestingCommons { val prop = AND(scriptIsCorrect, If(EQ(SizeOf(Inputs), 1), EQ(scriptHash, script1Hash), EQ(scriptHash, script2Hash))).toSigmaProp - val input1 = ErgoBox(20, prop, 0) + val input1 = testBox(20, prop, 0) val tx = UnsignedErgoLikeTransaction(IndexedSeq(input1).map(i => new UnsignedInput(i.id)), - IndexedSeq(ErgoBox(1, ErgoScriptPredef.TrueProp, 0))) + IndexedSeq(testBox(1, ErgoScriptPredef.TrueProp, 0))) val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, @@ -101,13 +102,13 @@ class MASTExampleSpecification extends SigmaTestingCommons { val prop = AND(merklePathToScript, scriptIsCorrect).toSigmaProp val recipientProposition = new ContextEnrichingTestProvingInterpreter().dlogSecrets.head.publicImage - val selfBox = ErgoBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(treeData))) + val selfBox = testBox(20, ErgoScriptPredef.TrueProp, 0, Seq(), Map(reg1 -> AvlTreeConstant(treeData))) val ctx = ErgoLikeContextTesting( currentHeight = 50, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), - createTransaction(ErgoBox(1, recipientProposition, 0)), + createTransaction(testBox(1, recipientProposition, 0)), self = selfBox) avlProver.performOneOperation(Lookup(knownSecretTreeKey)) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala index 98098e43c9..507f8bb10d 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala @@ -2,7 +2,6 @@ package sigmastate.utxo.examples import java.math.BigInteger -import org.ergoplatform.{ErgoBox, ErgoLikeContext} import org.ergoplatform.ErgoBox.{R4, R5} import scorex.crypto.hash.Blake2b256 import sigmastate.AvlTreeData @@ -10,6 +9,7 @@ import sigmastate.Values.GroupElementConstant import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.basics.{DiffieHellmanTupleProverInput, ProveDHTuple} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.CryptoConstants import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ @@ -100,7 +100,7 @@ class MixExampleSpecification extends SigmaTestingCommons { val halfMixCreationHeight = 70 val mixAmount = 10 - val halfMixOutput = ErgoBox(mixAmount, halfMixScript, halfMixCreationHeight) + val halfMixOutput = testBox(mixAmount, halfMixScript, halfMixCreationHeight) // above halMixOutput is a Half-Mix box created by Alice. // a blockchain node verifying a block containing a spending transaction @@ -138,7 +138,7 @@ class MixExampleSpecification extends SigmaTestingCommons { val fullMixCreationHeight = 80 // if randomBit is 0 (i.e., false) below box is spendable by Alice, else by Bob - val fullMixOutput0 = ErgoBox(mixAmount, fullMixScript, fullMixCreationHeight, Nil, + val fullMixOutput0 = testBox(mixAmount, fullMixScript, fullMixCreationHeight, Nil, Map( R4 -> c0, R5 -> c1 @@ -146,7 +146,7 @@ class MixExampleSpecification extends SigmaTestingCommons { ) // if randomBit is 1 (i.e., true) below box is spendable by Alice, else by Bob - val fullMixOutput1 = ErgoBox(mixAmount, fullMixScript, fullMixCreationHeight, Nil, + val fullMixOutput1 = testBox(mixAmount, fullMixScript, fullMixCreationHeight, Nil, Map( R4 -> c1, R5 -> c0 @@ -184,7 +184,7 @@ class MixExampleSpecification extends SigmaTestingCommons { val carolPubKey: ProveDlog = carol.dlogSecrets.head.publicImage val spendHeight = 90 - val carolOutput = ErgoBox(mixAmount, carolPubKey, spendHeight) + val carolOutput = testBox(mixAmount, carolPubKey, spendHeight) // normally this transaction would be invalid, but we're not checking it in this test val spendingTx = createTransaction(carolOutput) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala index 9e67015e57..edaf3cc23b 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala @@ -13,6 +13,7 @@ import sigmastate._ import sigmastate.eval._ import sigmastate.lang.Terms._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.CryptoConstants import org.ergoplatform._ import org.ergoplatform.dsl.{ContractSpec, SigmaContractSyntax, StdContracts, TestContractSpec} @@ -98,7 +99,7 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => val z = (r + e.bigInteger.multiply(oraclePrivKey.w)).mod(group.order).bigInteger - val oracleBox = ErgoBox( + val oracleBox = testBox( value = 1L, ergoTree = oraclePubKey, creationHeight = 0, @@ -154,7 +155,7 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => avlProver.performOneOperation(Lookup(ADKey @@ oracleBox.id)) val proof = avlProver.generateProof() - val newBox1 = ErgoBox(20, alicePubKey, 0, boxIndex = 2) + val newBox1 = testBox(20, alicePubKey, 0, boxIndex = 2) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = createTransaction(newBoxes) @@ -163,14 +164,14 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => val propAlice = withinTimeframe(sinceHeight, timeout, alicePubKey.isProven)(oracleProp).toSigmaProp - val sAlice = ErgoBox(10, propAlice, 0, Seq(), Map(), boxIndex = 3) + val sAlice = testBox(10, propAlice, 0, Seq(), Map(), boxIndex = 3) //"along with a brother" script val propAlong = AND( EQ(SizeOf(Inputs), IntConstant(2)), EQ(ExtractId(ByIndex(Inputs, 0)), ByteArrayConstant(sAlice.id))) val propBob = withinTimeframe(sinceHeight, timeout, bobPubKey.isProven)(propAlong).toSigmaProp - val sBob = ErgoBox(10, propBob, 0, Seq(), Map(), boxIndex = 4) + val sBob = testBox(10, propBob, 0, Seq(), Map(), boxIndex = 4) val ctx = ErgoLikeContextTesting( currentHeight = 50, @@ -223,7 +224,7 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => val temperature: Long = 18 - val oracleBox = ErgoBox( + val oracleBox = testBox( value = 1L, ergoTree = oraclePubKey, creationHeight = 0, @@ -242,10 +243,10 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => ).toSigmaProp val sOracle = oracleBox - val sAlice = ErgoBox(10, prop, 0, Seq(), Map()) - val sBob = ErgoBox(10, prop, 0, Seq(), Map()) + val sAlice = testBox(10, prop, 0, Seq(), Map()) + val sBob = testBox(10, prop, 0, Seq(), Map()) - val newBox1 = ErgoBox(20, alicePubKey, 0) + val newBox1 = testBox(20, alicePubKey, 0) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = createTransaction(newBoxes) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala index be1b72a08d..2679ab1aa1 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala @@ -2,16 +2,15 @@ package sigmastate.utxo.examples import org.ergoplatform.ErgoBox.{R4, R5, R6, R7} -import org.ergoplatform._ import scorex.crypto.hash.Blake2b256 import scorex.utils.Random -import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant, SigmaBoolean, SigmaPropConstant} +import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant, SigmaPropConstant} import sigmastate._ import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ -import sigmastate.utxo._ class RPSGameExampleSpecification extends SigmaTestingCommons { implicit lazy val IR = new TestingIRContext @@ -113,7 +112,7 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { val halfGameCreationHeight = 70 val playAmount = 10 // LongConstant(10) - val halfGameOutput = ErgoBox(playAmount, halfGameScript, halfGameCreationHeight) + val halfGameOutput = testBox(playAmount, halfGameScript, halfGameCreationHeight) ///////////////////////////////////////////////////////// //// above halfGameOutput is a Half-Game "box" created by Alice. @@ -134,7 +133,7 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { val bobDeadline = 120 // height after which it become's Bob's money val b:Byte = (scala.util.Random.nextInt.abs % 3).toByte - val fullGameOutput0 = ErgoBox(playAmount, fullGameScript, fullGameCreationHeight, Nil, + val fullGameOutput0 = testBox(playAmount, fullGameScript, fullGameCreationHeight, Nil, Map( R4 -> ByteConstant(b), R5 -> SigmaPropConstant(bobPubKey), @@ -143,7 +142,7 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { ) ) - val fullGameOutput1 = ErgoBox(playAmount, fullGameScript, fullGameCreationHeight, Nil, + val fullGameOutput1 = testBox(playAmount, fullGameScript, fullGameCreationHeight, Nil, Map( R4 -> ByteConstant(b), R5 -> SigmaPropConstant(bobPubKey), @@ -183,7 +182,7 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { val carolPubKey:ProveDlog = carol.dlogSecrets.head.publicImage // note that playAmount below is not checked. It could be anything. - val gameOverOutput = ErgoBox(playAmount, carolPubKey, gameOverHeight) + val gameOverOutput = testBox(playAmount, carolPubKey, gameOverHeight) // normally this transaction would be invalid, but we're not checking it in this test val gameOverTx = createTransaction(gameOverOutput) @@ -272,7 +271,7 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { // assume Bob is paying to Carol // note that playAmount*2 below is not checked. It could be anything. - val defaultWinOutput = ErgoBox(playAmount*2, carolPubKey, defaultWinHeight) + val defaultWinOutput = testBox(playAmount*2, carolPubKey, defaultWinHeight) //normally this transaction would invalid (why?), but we're not checking it in this test val defaultWinTx = createTransaction(defaultWinOutput) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala index ca736e18dc..60a07f4999 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala @@ -6,6 +6,7 @@ import scorex.crypto.hash.Blake2b256 import sigmastate.Values.{IntConstant, SigmaPropConstant} import sigmastate._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ @@ -125,7 +126,7 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { // In the example, we don't create the transaction; we just create a box below - val depositOutput = ErgoBox(depositAmount, depositAddress.script, depositHeight) + val depositOutput = testBox(depositAmount, depositAddress.script, depositHeight) // Now Alice wants to give Bob some amount from the wallet in a "reversible" way. @@ -133,7 +134,7 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { val withdrawHeight = 101 val bobDeadline = withdrawHeight+blocksIn24h - val reversibleWithdrawOutput = ErgoBox(withdrawAmount, withdrawScript, withdrawHeight, Nil, + val reversibleWithdrawOutput = testBox(withdrawAmount, withdrawScript, withdrawHeight, Nil, Map( R4 -> SigmaPropConstant(bobPubKey), R5 -> IntConstant(bobDeadline) @@ -167,7 +168,7 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { val bobSpendAmount = 10 val bobSpendHeight = bobDeadline+1 - val bobSpendOutput = ErgoBox(bobSpendAmount, davePubKey, bobSpendHeight) + val bobSpendOutput = testBox(bobSpendAmount, davePubKey, bobSpendHeight) //normally this transaction would be invalid (why?), but we're not checking it in this test val bobSpendTx = createTransaction(bobSpendOutput) @@ -194,7 +195,7 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { val carolSpendHeight = bobDeadline - 1 // Carol sends to Dave - val carolSpendOutput = ErgoBox(carolSpendAmount, davePubKey, carolSpendHeight) + val carolSpendOutput = testBox(carolSpendAmount, davePubKey, carolSpendHeight) //normally this transaction would be invalid (why?), but we're not checking it in this test val carolSpendTx = createTransaction(carolSpendOutput) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala index 10e391a893..ae80e4311d 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala @@ -7,6 +7,7 @@ import sigmastate.Values.{BooleanConstant, ByteArrayConstant, ByteConstant, Fals import sigmastate._ import sigmastate.eval._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.ContextExtension import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer @@ -51,8 +52,8 @@ class Rule110Specification extends SigmaTestingCommons { | (OUTPUTS(0).propositionBytes == SELF.propositionBytes) }""".stripMargin).asBoolValue.toSigmaProp - val input = ErgoBox(1, prop, 0, Seq(), Map(reg1 -> ByteArrayConstant(Array[Byte](0, 1, 1, 0, 1, 0)))) - val output = ErgoBox(1, prop, 0, Seq(), Map(reg1 -> ByteArrayConstant(Array[Byte](1, 1, 1, 1, 1, 0)))) + val input = testBox(1, prop, 0, Seq(), Map(reg1 -> ByteArrayConstant(Array[Byte](0, 1, 1, 0, 1, 0)))) + val output = testBox(1, prop, 0, Seq(), Map(reg1 -> ByteArrayConstant(Array[Byte](1, 1, 1, 1, 1, 0)))) val tx = UnsignedErgoLikeTransaction(IndexedSeq(new UnsignedInput(input.id)), IndexedSeq(output)) val ctx = ErgoLikeContextTesting( @@ -206,12 +207,12 @@ class Rule110Specification extends SigmaTestingCommons { val prop = AND(scriptIsCorrect, OR(normalCaseConditions, rightmostConditions, nLeftmostConditions, leftmostConditions)).toSigmaProp // test normal case - val nIn0 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-2), YReg -> ByteConstant(0), ValReg -> t)) - val nIn1 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-1), YReg -> ByteConstant(0), ValReg -> f)) - val nIn2 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(0), YReg -> ByteConstant(0), ValReg -> t)) - val nOut0 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-1), YReg -> ByteConstant(-1), ValReg -> t)) - val nOut1 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-1), YReg -> ByteConstant(-1), ValReg -> t)) - val nOut2 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-1), YReg -> ByteConstant(-1), ValReg -> t)) + val nIn0 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-2), YReg -> ByteConstant(0), ValReg -> t)) + val nIn1 = testBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-1), YReg -> ByteConstant(0), ValReg -> f)) + val nIn2 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(0), YReg -> ByteConstant(0), ValReg -> t)) + val nOut0 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-1), YReg -> ByteConstant(-1), ValReg -> t)) + val nOut1 = testBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-1), YReg -> ByteConstant(-1), ValReg -> t)) + val nOut2 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-1), YReg -> ByteConstant(-1), ValReg -> t)) val nTx = UnsignedErgoLikeTransaction(IndexedSeq(nIn0, nIn1, nIn2).map(i => new UnsignedInput(i.id)), IndexedSeq(nOut0, nOut1, nOut2)) val nProver = new ContextEnrichingTestProvingInterpreter() @@ -229,11 +230,11 @@ class Rule110Specification extends SigmaTestingCommons { verifier.verify(prop, nCtx, nProof, fakeMessage).get._1 shouldBe true // test rightmost case - val rIn0 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-1), YReg -> ByteConstant(0), ValReg -> t)) - val rIn1 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(0), YReg -> ByteConstant(0), ValReg -> t)) - val rOut0 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(0), YReg -> ByteConstant(-1), ValReg -> t)) - val rOut1 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(0), YReg -> ByteConstant(-1), ValReg -> t)) - val rOut2 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(0), YReg -> ByteConstant(-1), ValReg -> t)) + val rIn0 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-1), YReg -> ByteConstant(0), ValReg -> t)) + val rIn1 = testBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(0), YReg -> ByteConstant(0), ValReg -> t)) + val rOut0 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(0), YReg -> ByteConstant(-1), ValReg -> t)) + val rOut1 = testBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(0), YReg -> ByteConstant(-1), ValReg -> t)) + val rOut2 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(0), YReg -> ByteConstant(-1), ValReg -> t)) val rTx = UnsignedErgoLikeTransaction(IndexedSeq(rIn0, rIn1).map(i => new UnsignedInput(i.id)), IndexedSeq(rOut0, rOut1, rOut2)) val rProver = new ContextEnrichingTestProvingInterpreter() @@ -251,11 +252,11 @@ class Rule110Specification extends SigmaTestingCommons { verifier.verify(prop, rCtx, rProof, fakeMessage).get._1 shouldBe true // test next to leftmost case - val lnIn0 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-6), YReg -> ByteConstant(-6), ValReg -> t)) - val lnIn1 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-5), YReg -> ByteConstant(-6), ValReg -> t)) - val lnOut0 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-6), YReg -> ByteConstant(-7), ValReg -> t)) - val lnOut1 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-6), YReg -> ByteConstant(-7), ValReg -> t)) - val lnOut2 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-6), YReg -> ByteConstant(-7), ValReg -> t)) + val lnIn0 = testBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-6), YReg -> ByteConstant(-6), ValReg -> t)) + val lnIn1 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-5), YReg -> ByteConstant(-6), ValReg -> t)) + val lnOut0 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-6), YReg -> ByteConstant(-7), ValReg -> t)) + val lnOut1 = testBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-6), YReg -> ByteConstant(-7), ValReg -> t)) + val lnOut2 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-6), YReg -> ByteConstant(-7), ValReg -> t)) val lnTx = UnsignedErgoLikeTransaction(IndexedSeq(lnIn0, lnIn1).map(i => new UnsignedInput(i.id)), IndexedSeq(lnOut0, lnOut1, lnOut2)) val lnProver = new ContextEnrichingTestProvingInterpreter() @@ -273,10 +274,10 @@ class Rule110Specification extends SigmaTestingCommons { verifier.verify(prop, lnCtx, lnProof, fakeMessage).get._1 shouldBe true // test leftmost case - val lIn0 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-6), YReg -> ByteConstant(-6), ValReg -> t)) - val lOut0 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-7), YReg -> ByteConstant(-7), ValReg -> t)) - val lOut1 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-7), YReg -> ByteConstant(-7), ValReg -> t)) - val lOut2 = ErgoBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-7), YReg -> ByteConstant(-7), ValReg -> t)) + val lIn0 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-6), YReg -> ByteConstant(-6), ValReg -> t)) + val lOut0 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-7), YReg -> ByteConstant(-7), ValReg -> t)) + val lOut1 = testBox(1, prop, 0, Seq(), Map(MidReg -> t, XReg -> ByteConstant(-7), YReg -> ByteConstant(-7), ValReg -> t)) + val lOut2 = testBox(1, prop, 0, Seq(), Map(MidReg -> f, XReg -> ByteConstant(-7), YReg -> ByteConstant(-7), ValReg -> t)) val lTx = UnsignedErgoLikeTransaction(IndexedSeq(lIn0).map(i => new UnsignedInput(i.id)), IndexedSeq(lOut0, lOut1, lOut2)) val lProver = new ContextEnrichingTestProvingInterpreter() @@ -400,7 +401,7 @@ class Rule110Specification extends SigmaTestingCommons { val row = RowReg -> LongConstant(0) val column = ColumnReg -> LongConstant(col) val value = if (col == 15) ValueReg -> TrueLeaf else ValueReg -> FalseLeaf - ErgoBox(0L, prop, 0, Nil, Map(row, column, value), txId.toModifierId, col.toShort) + testBox(0L, prop, 0, Nil, Map(row, column, value), txId.toModifierId, col.toShort) } val initBlock = FullBlock( diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala index 5b9b1300ac..ad0e561324 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala @@ -1,14 +1,13 @@ package sigmastate.utxo.examples -import org.ergoplatform.ErgoBox.{R4, R5} import org.ergoplatform._ -import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant} +import sigmastate.Values.IntConstant import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.InterpreterException -import sigmastate.utxo._ class TimedPaymentExampleSpecification extends SigmaTestingCommons { @@ -45,7 +44,7 @@ class TimedPaymentExampleSpecification extends SigmaTestingCommons { // In the example, we don't create the transaction; we just create a box below - val depositOutput = ErgoBox(depositAmount, address.script, depositHeight) + val depositOutput = testBox(depositAmount, address.script, depositHeight) // Now Alice wants to give Bob (coffee shop owner) some amount from the wallet in a "timed" way. @@ -53,7 +52,7 @@ class TimedPaymentExampleSpecification extends SigmaTestingCommons { val withdrawHeight = 100 val confDeadline = 110 - val timedWithdrawOutput = ErgoBox(withdrawAmount, bobPubKey, withdrawHeight) + val timedWithdrawOutput = testBox(withdrawAmount, bobPubKey, withdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val withdrawTx = createTransaction(IndexedSeq(timedWithdrawOutput)) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/TrustlessLETS.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/TrustlessLETS.scala index 5ec77e0717..501e5d10e8 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/TrustlessLETS.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/TrustlessLETS.scala @@ -1,9 +1,9 @@ package sigmastate.utxo.examples -import org.ergoplatform._ import scorex.crypto.hash.Blake2b256 import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ @@ -107,7 +107,7 @@ class TrustlessLETS1 extends SigmaTestingCommons { val tokenBoxCreationHeight = 70 val tokenAmount = 10 // LongConstant(10) - val tokenBoxOutput = ErgoBox(tokenAmount, tokenScript, tokenBoxCreationHeight) + val tokenBoxOutput = testBox(tokenAmount, tokenScript, tokenBoxCreationHeight) } @@ -209,7 +209,7 @@ class TrustlessLETS2 extends SigmaTestingCommons { val tokenBoxCreationHeight = 70 val tokenAmount = 10 // LongConstant(10) - val tokenBoxOutput = ErgoBox(tokenAmount, tokenScript, tokenBoxCreationHeight) + val tokenBoxOutput = testBox(tokenAmount, tokenScript, tokenBoxCreationHeight) } @@ -323,7 +323,7 @@ class TrustlessLETS3 extends SigmaTestingCommons { val tokenBoxCreationHeight = 70 val tokenAmount = 10 // LongConstant(10) - val tokenBoxOutput = ErgoBox(tokenAmount, tokenScript, tokenBoxCreationHeight) + val tokenBoxOutput = testBox(tokenAmount, tokenScript, tokenBoxCreationHeight) } @@ -430,7 +430,7 @@ class TrustlessLETS4 extends SigmaTestingCommons { val tokenBoxCreationHeight = 70 val tokenAmount = 10 // LongConstant(10) - val tokenBoxOutput = ErgoBox(tokenAmount, tokenScript, tokenBoxCreationHeight) + val tokenBoxOutput = testBox(tokenAmount, tokenScript, tokenBoxCreationHeight) } diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala index 606d64f17a..46d67b19d3 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala @@ -2,16 +2,15 @@ package sigmastate.utxo.examples import org.ergoplatform.ErgoBox.{R4, R5, R6} -import org.ergoplatform._ import scorex.crypto.hash.Blake2b256 import scorex.utils.Random import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant, SigmaPropConstant} import sigmastate._ import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ -import sigmastate.utxo._ class XorGameExampleSpecification extends SigmaTestingCommons { private implicit lazy val IR: TestingIRContext = new TestingIRContext @@ -107,7 +106,7 @@ class XorGameExampleSpecification extends SigmaTestingCommons { val halfGameCreationHeight = 70 val playAmount = 10 // LongConstant(10) - val halfGameOutput = ErgoBox(playAmount, halfGameScript, halfGameCreationHeight) + val halfGameOutput = testBox(playAmount, halfGameScript, halfGameCreationHeight) ///////////////////////////////////////////////////////// //// above halfGameOutput is a Half-Game "box" created by Alice. @@ -133,7 +132,7 @@ class XorGameExampleSpecification extends SigmaTestingCommons { // // val abortHalfGameOutput = ErgoBox(playAmount, carolPubKey, abortHalfGameHeight) // gives error - val abortHalfGameOutput = ErgoBox(playAmount, carolPubKey, abortHalfGameHeight, Nil, + val abortHalfGameOutput = testBox(playAmount, carolPubKey, abortHalfGameHeight, Nil, Map( R4 -> ByteConstant(0), // dummy data. Has to be given, even though not needed as per halfGameScript R5 -> SigmaPropConstant((new ContextEnrichingTestProvingInterpreter).dlogSecrets.head.publicImage), // dummy statement @@ -169,7 +168,7 @@ class XorGameExampleSpecification extends SigmaTestingCommons { val bobDeadline = 120 // height after which it become's Bob's money val b:Byte = if (scala.util.Random.nextBoolean) 0x01 else 0x00 - val fullGameOutput = ErgoBox(playAmount*2, fullGameScript, fullGameCreationHeight, Nil, + val fullGameOutput = testBox(playAmount*2, fullGameScript, fullGameCreationHeight, Nil, Map( R4 -> ByteConstant(b), R5 -> SigmaPropConstant(bobPubKey), @@ -225,7 +224,7 @@ class XorGameExampleSpecification extends SigmaTestingCommons { // assume winner is paying to Carol // note that playAmount*2 below is not checked. It could be anything. - val gameOverOutput = ErgoBox(playAmount*2, carolPubKey, gameOverHeight) + val gameOverOutput = testBox(playAmount*2, carolPubKey, gameOverHeight) //normally this transaction would invalid (why?), but we're not checking it in this test val gameOverTx = createTransaction(gameOverOutput) @@ -252,7 +251,7 @@ class XorGameExampleSpecification extends SigmaTestingCommons { // assume Bob is paying to Carol // note that playAmount*2 below is not checked. It could be anything. - val defaultWinOutput = ErgoBox(playAmount*2, carolPubKey, defaultWinHeight) + val defaultWinOutput = testBox(playAmount*2, carolPubKey, defaultWinHeight) //normally this transaction would invalid (why?), but we're not checking it in this test val defaultWinTx = createTransaction(defaultWinOutput) diff --git a/sigmastate/src/test/scala/special/sigma/ContractsTestkit.scala b/sigmastate/src/test/scala/special/sigma/ContractsTestkit.scala index 8e67330bc9..a01720b0d1 100644 --- a/sigmastate/src/test/scala/special/sigma/ContractsTestkit.scala +++ b/sigmastate/src/test/scala/special/sigma/ContractsTestkit.scala @@ -1,12 +1,12 @@ package special.sigma -import org.ergoplatform.ErgoBox import scalan._ import special.collection.{Coll, CollOverArrayBuilder} import scalan.RType import sigmastate.{AvlTreeData, TrivialProp} import sigmastate.eval._ import sigmastate.eval.Extensions._ +import sigmastate.helpers.TestingHelpers._ trait ContractsTestkit { val R0 = 0.toByte; @@ -57,7 +57,7 @@ trait ContractsTestkit { val AliceId = Array[Byte](1) // 0x0001 def newAliceBox(id: Byte, value: Long): Box = { - val ergoBox = ErgoBox(value, TrivialProp.TrueProp.toSigmaProp, 0, Seq(), Map()) + val ergoBox = testBox(value, TrivialProp.TrueProp.toSigmaProp, 0, Seq(), Map()) new CostingBox(false, ergoBox) } diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslSpec.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala similarity index 57% rename from sigmastate/src/test/scala/special/sigma/SigmaDslSpec.scala rename to sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala index 32865c543e..86b996700f 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslSpec.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala @@ -28,6 +28,8 @@ import sigmastate.utxo._ import special.collection._ import sigmastate.serialization.OpCodes.OpCode import sigmastate.utils.Helpers +import sigmastate.utils.Helpers._ +import sigmastate.helpers.TestingHelpers._ import scala.reflect.ClassTag import scala.util.{DynamicVariable, Success, Failure, Try} @@ -40,10 +42,12 @@ import scala.math.Ordering /** This suite tests every method of every SigmaDsl type to be equivalent to * the evaluation of the corresponding ErgoScript operation */ -class SigmaDslSpec extends SigmaDslTesting { suite => +class SigmaDslSpecification extends SigmaDslTesting { suite => override implicit val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 30) + implicit def IR = createIR() + ///===================================================== /// Boolean type operations ///----------------------------------------------------- @@ -70,12 +74,12 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) )) val cases = Seq( - ((true, true), Try(false)), - ((true, false), Try(true)), - ((false, false), Try(false)), - ((false, true), Try(true)) + (true, true) -> Success(Expected(false, 36518)), + (true, false) -> Success(Expected(true, 36518)), + (false, false) -> Success(Expected(false, 36518)), + (false, true) -> Success(Expected(true, 36518)) ) - testCases(cases, binXor) + verifyCases(cases, binXor) } property("BinXor(logical XOR) test") { @@ -92,14 +96,14 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) )) val cases = Seq( - ((1095564593, true), Success(true)), - ((-901834021, true), Success(true)), - ((595045530, false), Success(false)), - ((-1157998227, false), Success(false)), - ((0, true), Success(false)), - ((0, false), Success(true)) + (1095564593, true) -> Success(Expected(true, 36865)), + (-901834021, true) -> Success(Expected(true, 36865)), + (595045530, false) -> Success(Expected(false, 36865)), + (-1157998227, false) -> Success(Expected(false, 36865)), + (0, true) -> Success(Expected(false, 36865)), + (0, false) -> Success(Expected(true, 36865)) ) - testCases(cases, xor) + verifyCases(cases, xor) } property("&& boolean equivalence") { @@ -113,12 +117,12 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) )) val cases = Seq( - ((false, true), Success(false)), - ((false, false), Success(false)), - ((true, true), Success(true)), - ((true, false), Success(false)) + (false, true) -> Success(Expected(false, 38241)), + (false, false) -> Success(Expected(false, 38241)), + (true, true) -> Success(Expected(true, 38241)), + (true, false) -> Success(Expected(false, 38241)) ) - testCases(cases, eq) + verifyCases(cases, eq) } property("|| boolean equivalence") { @@ -132,18 +136,18 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) )) val cases = Seq( - ((true, false), Success(true)), - ((true, true), Success(true)), - ((false, false), Success(false)), - ((false, true), Success(true)) + (true, false) -> Success(Expected(true, 38241)), + (true, true) -> Success(Expected(true, 38241)), + (false, false) -> Success(Expected(false, 38241)), + (false, true) -> Success(Expected(true, 38241)) ) - testCases(cases, eq) + verifyCases(cases, eq) } property("lazy || and && boolean equivalence") { - testCases( + verifyCases( Seq( - (true, Success(true)), + (true, Success(Expected(true, 38467))), (false, Failure(new ArithmeticException("/ by zero"))) ), existingFeature((x: Boolean) => x || (1 / 0 == 1), @@ -156,10 +160,10 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( + verifyCases( Seq( (true, Failure(new ArithmeticException("/ by zero"))), - (false, Success(false)) + (false, Success(Expected(false, 38467))) ), existingFeature((x: Boolean) => x && (1 / 0 == 1), "{ (x: Boolean) => x && (1 / 0 == 1) }", @@ -171,10 +175,10 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( + verifyCases( Seq( - (false, Success(false)), - (true, Success(true)) + (false, Success(Expected(false, 40480))), + (true, Success(Expected(true, 40480))) ), existingFeature((x: Boolean) => x && (x || (1 / 0 == 1)), "{ (x: Boolean) => x && (x || (1 / 0 == 1)) }", @@ -189,10 +193,10 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( + verifyCases( Seq( - (false, Success(false)), - (true, Success(true)) + (false, Success(Expected(false, 42493))), + (true, Success(Expected(true, 42493))) ), existingFeature((x: Boolean) => x && (x && (x || (1 / 0 == 1))), "{ (x: Boolean) => x && (x && (x || (1 / 0 == 1))) }", @@ -210,10 +214,10 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( + verifyCases( Seq( - (false, Success(false)), - (true, Success(true)) + (false, Success(Expected(false, 44506))), + (true, Success(Expected(true, 44506))) ), existingFeature((x: Boolean) => x && (x && (x && (x || (1 / 0 == 1)))), "{ (x: Boolean) => x && (x && (x && (x || (1 / 0 == 1)))) }", @@ -234,10 +238,10 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( + verifyCases( Seq( (false, Failure(new ArithmeticException("/ by zero"))), - (true, Success(true)) + (true, Success(Expected(true, 43281))) ), existingFeature((x: Boolean) => !(!x && (1 / 0 == 1)) && (x || (1 / 0 == 1)), "{ (x: Boolean) => !(!x && (1 / 0 == 1)) && (x || (1 / 0 == 1)) }", @@ -257,9 +261,9 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( + verifyCases( Seq( - (true, Success(true)), + (true, Success(Expected(true, 40480))), (false, Failure(new ArithmeticException("/ by zero"))) ), existingFeature((x: Boolean) => (x || (1 / 0 == 1)) && x, @@ -275,9 +279,9 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( + verifyCases( Seq( - (true, Success(true)), + (true, Success(Expected(true, 43149))), (false, Failure(new ArithmeticException("/ by zero"))) ), existingFeature((x: Boolean) => (x || (1 / 0 == 1)) && (x || (1 / 0 == 1)), @@ -296,9 +300,9 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( + verifyCases( Seq( - (true, Success(true)), + (true, Success(Expected(true, 45950))), (false, Failure(new ArithmeticException("/ by zero"))) ), existingFeature( @@ -323,10 +327,10 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( + verifyCases( Seq( (false, Failure(new ArithmeticException("/ by zero"))), - (true, Success(true)) + (true, Success(Expected(true, 48862))) ), existingFeature( (x: Boolean) => (!(!x && (1 / 0 == 1)) || (1 / 0 == 0)) && (!(!x && (1 / 0 == 1)) || (1 / 0 == 1)), @@ -363,110 +367,128 @@ class SigmaDslSpec extends SigmaDslTesting { suite => SByte.upcast(0.toByte) shouldBe 0.toByte // boundary test case SByte.downcast(0.toByte) shouldBe 0.toByte // boundary test case - testCases( - Seq( - (0.toByte, Success(0.toByte)), - (1.toByte, Success(1.toByte)), - (55.toByte, Success(55.toByte)), - (Byte.MaxValue, Success(Byte.MaxValue)), - (-1.toByte, Success(-1.toByte)), - (-65.toByte, Success(-65.toByte)), - (Byte.MinValue, Success(Byte.MinValue)) - ), + verifyCases( + { + def expect(v: Byte) = Success(Expected(v, 35798)) + Seq( + (0.toByte, expect(0.toByte)), + (1.toByte, expect(1.toByte)), + (55.toByte, expect(55.toByte)), + (Byte.MaxValue, expect(Byte.MaxValue)), + (-1.toByte, expect(-1.toByte)), + (-65.toByte, expect(-65.toByte)), + (Byte.MinValue, expect(Byte.MinValue)) + ) + }, existingFeature( (x: Byte) => x.toByte, "{ (x: Byte) => x.toByte }", FuncValue(Vector((1, SByte)), ValUse(1, SByte)))) - testCases( - Seq( - (0.toByte, Success(0.toShort)), - (1.toByte, Success(1.toShort)), - (55.toByte, Success(55.toShort)), - (Byte.MaxValue, Success(Byte.MaxValue.toShort)), - (-1.toByte, Success(-1.toShort)), - (-65.toByte, Success(-65.toShort)), - (Byte.MinValue, Success(Byte.MinValue.toShort)) - ), + verifyCases( + { + def expected(v: Short) = Success(Expected(v, 35902)) + Seq( + (0.toByte, expected(0.toShort)), + (1.toByte, expected(1.toShort)), + (55.toByte, expected(55.toShort)), + (Byte.MaxValue, expected(Byte.MaxValue.toShort)), + (-1.toByte, expected(-1.toShort)), + (-65.toByte, expected(-65.toShort)), + (Byte.MinValue, expected(Byte.MinValue.toShort)) + ) + }, existingFeature( (x: Byte) => x.toShort, "{ (x: Byte) => x.toShort }", FuncValue(Vector((1, SByte)), Upcast(ValUse(1, SByte), SShort)))) - testCases( - Seq( - (0.toByte, Success(0)), - (1.toByte, Success(1)), - (55.toByte, Success(55)), - (Byte.MaxValue, Success(Byte.MaxValue.toInt)), - (-1.toByte, Success(-1)), - (-65.toByte, Success(-65)), - (Byte.MinValue, Success(Byte.MinValue.toInt)) - ), + verifyCases( + { + def expected(v: Int) = Success(Expected(v, 35902)) + Seq( + (0.toByte, expected(0)), + (1.toByte, expected(1)), + (55.toByte, expected(55)), + (Byte.MaxValue, expected(Byte.MaxValue.toInt)), + (-1.toByte, expected(-1)), + (-65.toByte, expected(-65)), + (Byte.MinValue, expected(Byte.MinValue.toInt)) + ) + }, existingFeature( (x: Byte) => x.toInt, "{ (x: Byte) => x.toInt }", FuncValue(Vector((1, SByte)), Upcast(ValUse(1, SByte), SInt)))) - testCases( - Seq( - (0.toByte, Success(0L)), - (1.toByte, Success(1L)), - (55.toByte, Success(55L)), - (Byte.MaxValue, Success(Byte.MaxValue.toLong)), - (-1.toByte, Success(-1L)), - (-65.toByte, Success(-65L)), - (Byte.MinValue, Success(Byte.MinValue.toLong)) - ), + verifyCases( + { + def expected(v: Long) = Success(Expected(v, 35902)) + Seq( + (0.toByte, expected(0L)), + (1.toByte, expected(1L)), + (55.toByte, expected(55L)), + (Byte.MaxValue, expected(Byte.MaxValue.toLong)), + (-1.toByte, expected(-1L)), + (-65.toByte, expected(-65L)), + (Byte.MinValue, expected(Byte.MinValue.toLong)) + ) + }, existingFeature( (x: Byte) => x.toLong, "{ (x: Byte) => x.toLong }", FuncValue(Vector((1, SByte)), Upcast(ValUse(1, SByte), SLong)))) - testCases( - Seq( - (0.toByte, Success(CBigInt(new BigInteger("0", 16)))), - (1.toByte, Success(CBigInt(new BigInteger("1", 16)))), - (-1.toByte, Success(CBigInt(new BigInteger("-1", 16)))), - (127.toByte, Success(CBigInt(new BigInteger("7f", 16)))), - (-128.toByte, Success(CBigInt(new BigInteger("-80", 16)))), - (90.toByte, Success(CBigInt(new BigInteger("5a", 16)))), - (-53.toByte, Success(CBigInt(new BigInteger("-35", 16)))) - ), + verifyCases( + { + def expected(v: BigInt) = Success(Expected(v, 35932)) + Seq( + (0.toByte, expected(CBigInt(new BigInteger("0", 16)))), + (1.toByte, expected(CBigInt(new BigInteger("1", 16)))), + (-1.toByte, expected(CBigInt(new BigInteger("-1", 16)))), + (127.toByte, expected(CBigInt(new BigInteger("7f", 16)))), + (-128.toByte, expected(CBigInt(new BigInteger("-80", 16)))), + (90.toByte, expected(CBigInt(new BigInteger("5a", 16)))), + (-53.toByte, expected(CBigInt(new BigInteger("-35", 16)))) + ) + }, existingFeature( (x: Byte) => x.toBigInt, "{ (x: Byte) => x.toBigInt }", FuncValue(Vector((1, SByte)), Upcast(ValUse(1, SByte), SBigInt)))) val n = ExactNumeric.ByteIsExactNumeric - testCases( - Seq( - ((-128.toByte, -128.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((-128.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), - ((-128.toByte, 17.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((-128.toByte, 127.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((-120.toByte, 82.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((-103.toByte, 1.toByte), Success((-102.toByte, (-104.toByte, (-103.toByte, (-103.toByte, 0.toByte)))))), - ((-90.toByte, 37.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((-78.toByte, -111.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((-71.toByte, -44.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((-53.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), - ((-34.toByte, 8.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((-24.toByte, 127.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((-1.toByte, -1.toByte), Success((-2.toByte, (0.toByte, (1.toByte, (1.toByte, 0.toByte)))))), - ((-1.toByte, 23.toByte), Success((22.toByte, (-24.toByte, (-23.toByte, (0.toByte, -1.toByte)))))), - ((0.toByte, -128.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((0.toByte, -23.toByte), Success((-23.toByte, (23.toByte, (0.toByte, (0.toByte, 0.toByte)))))), - ((0.toByte, -1.toByte), Success((-1.toByte, (1.toByte, (0.toByte, (0.toByte, 0.toByte)))))), - ((0.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), - ((0.toByte, 1.toByte), Success((1.toByte, (-1.toByte, (0.toByte, (0.toByte, 0.toByte)))))), - ((0.toByte, 60.toByte), Success((60.toByte, (-60.toByte, (0.toByte, (0.toByte, 0.toByte)))))), - ((0.toByte, 127.toByte), Success((127.toByte, (-127.toByte, (0.toByte, (0.toByte, 0.toByte)))))), - ((1.toByte, -1.toByte), Success((0.toByte, (2.toByte, (-1.toByte, (-1.toByte, 0.toByte)))))), - ((1.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), - ((1.toByte, 26.toByte), Success((27.toByte, (-25.toByte, (26.toByte, (0.toByte, 1.toByte)))))), - ((7.toByte, -32.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((33.toByte, 1.toByte), Success((34.toByte, (32.toByte, (33.toByte, (33.toByte, 0.toByte)))))), - ((90.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), - ((127.toByte, -128.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((127.toByte, -47.toByte), Failure(new ArithmeticException("Byte overflow"))), - ((127.toByte, 127.toByte), Failure(new ArithmeticException("Byte overflow"))) - ), + verifyCases( + { + def success[T](v: (T, (T, (T, (T, T))))) = Success(Expected(v, 39654)) + Seq( + ((-128.toByte, -128.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((-128.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), + ((-128.toByte, 17.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((-128.toByte, 127.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((-120.toByte, 82.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((-103.toByte, 1.toByte), success((-102.toByte, (-104.toByte, (-103.toByte, (-103.toByte, 0.toByte)))))), + ((-90.toByte, 37.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((-78.toByte, -111.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((-71.toByte, -44.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((-53.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), + ((-34.toByte, 8.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((-24.toByte, 127.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((-1.toByte, -1.toByte), success((-2.toByte, (0.toByte, (1.toByte, (1.toByte, 0.toByte)))))), + ((-1.toByte, 23.toByte), success((22.toByte, (-24.toByte, (-23.toByte, (0.toByte, -1.toByte)))))), + ((0.toByte, -128.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((0.toByte, -23.toByte), success((-23.toByte, (23.toByte, (0.toByte, (0.toByte, 0.toByte)))))), + ((0.toByte, -1.toByte), success((-1.toByte, (1.toByte, (0.toByte, (0.toByte, 0.toByte)))))), + ((0.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), + ((0.toByte, 1.toByte), success((1.toByte, (-1.toByte, (0.toByte, (0.toByte, 0.toByte)))))), + ((0.toByte, 60.toByte), success((60.toByte, (-60.toByte, (0.toByte, (0.toByte, 0.toByte)))))), + ((0.toByte, 127.toByte), success((127.toByte, (-127.toByte, (0.toByte, (0.toByte, 0.toByte)))))), + ((1.toByte, -1.toByte), success((0.toByte, (2.toByte, (-1.toByte, (-1.toByte, 0.toByte)))))), + ((1.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), + ((1.toByte, 26.toByte), success((27.toByte, (-25.toByte, (26.toByte, (0.toByte, 1.toByte)))))), + ((7.toByte, -32.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((33.toByte, 1.toByte), success((34.toByte, (32.toByte, (33.toByte, (33.toByte, 0.toByte)))))), + ((90.toByte, 0.toByte), Failure(new ArithmeticException("/ by zero"))), + ((127.toByte, -128.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((127.toByte, -47.toByte), Failure(new ArithmeticException("Byte overflow"))), + ((127.toByte, 127.toByte), Failure(new ArithmeticException("Byte overflow"))) + ) + }, existingFeature( { (x: (Byte, Byte)) => val a = x._1; val b = x._2 @@ -556,108 +578,126 @@ class SigmaDslSpec extends SigmaDslTesting { suite => SShort.upcast(0.toShort) shouldBe 0.toShort // boundary test case SShort.downcast(0.toShort) shouldBe 0.toShort // boundary test case - testCases( - Seq( - (Short.MinValue, Failure(new ArithmeticException("Byte overflow"))), - (-21626.toShort, Failure(new ArithmeticException("Byte overflow"))), - (Byte.MinValue.toShort, Success(Byte.MinValue)), - (-1.toShort, Success(-1.toByte)), - (0.toShort, Success(0.toByte)), - (1.toShort, Success(1.toByte)), - (Byte.MaxValue.toShort, Success(Byte.MaxValue)), - (11768.toShort, Failure(new ArithmeticException("Byte overflow"))), - (Short.MaxValue, Failure(new ArithmeticException("Byte overflow"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35976)) + Seq( + (Short.MinValue, Failure(new ArithmeticException("Byte overflow"))), + (-21626.toShort, Failure(new ArithmeticException("Byte overflow"))), + (Byte.MinValue.toShort, success(Byte.MinValue)), + (-1.toShort, success(-1.toByte)), + (0.toShort, success(0.toByte)), + (1.toShort, success(1.toByte)), + (Byte.MaxValue.toShort, success(Byte.MaxValue)), + (11768.toShort, Failure(new ArithmeticException("Byte overflow"))), + (Short.MaxValue, Failure(new ArithmeticException("Byte overflow"))) + ) + }, existingFeature((x: Short) => x.toByteExact, "{ (x: Short) => x.toByte }", FuncValue(Vector((1, SShort)), Downcast(ValUse(1, SShort), SByte)))) - testCases( - Seq( - (-32768.toShort, Success(-32768.toShort)), - (-27798.toShort, Success(-27798.toShort)), - (-1.toShort, Success(-1.toShort)), - (0.toShort, Success(0.toShort)), - (1.toShort, Success(1.toShort)), - (27929.toShort, Success(27929.toShort)), - (32767.toShort, Success(32767.toShort)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35798)) + Seq( + (-32768.toShort, success(-32768.toShort)), + (-27798.toShort, success(-27798.toShort)), + (-1.toShort, success(-1.toShort)), + (0.toShort, success(0.toShort)), + (1.toShort, success(1.toShort)), + (27929.toShort, success(27929.toShort)), + (32767.toShort, success(32767.toShort)) + ) + }, existingFeature((x: Short) => x.toShort, "{ (x: Short) => x.toShort }", FuncValue(Vector((1, SShort)), ValUse(1, SShort)))) - testCases( - Seq( - (-32768.toShort, Success(-32768)), - (-21064.toShort, Success(-21064)), - (-1.toShort, Success(-1)), - (0.toShort, Success(0)), - (1.toShort, Success(1)), - (18388.toShort, Success(18388)), - (32767.toShort, Success(32767)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35902)) + Seq( + (-32768.toShort, success(-32768)), + (-21064.toShort, success(-21064)), + (-1.toShort, success(-1)), + (0.toShort, success(0)), + (1.toShort, success(1)), + (18388.toShort, success(18388)), + (32767.toShort, success(32767)) + ) + }, existingFeature((x: Short) => x.toInt, "{ (x: Short) => x.toInt }", FuncValue(Vector((1, SShort)), Upcast(ValUse(1, SShort), SInt)))) - testCases( - Seq( - (-32768.toShort, Success(-32768L)), - (-23408.toShort, Success(-23408L)), - (-1.toShort, Success(-1L)), - (0.toShort, Success(0L)), - (1.toShort, Success(1L)), - (23318.toShort, Success(23318L)), - (32767.toShort, Success(32767L)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35902)) + Seq( + (-32768.toShort, success(-32768L)), + (-23408.toShort, success(-23408L)), + (-1.toShort, success(-1L)), + (0.toShort, success(0L)), + (1.toShort, success(1L)), + (23318.toShort, success(23318L)), + (32767.toShort, success(32767L)) + ) + }, existingFeature((x: Short) => x.toLong, "{ (x: Short) => x.toLong }", FuncValue(Vector((1, SShort)), Upcast(ValUse(1, SShort), SLong)))) - testCases( - Seq( - (-32768.toShort, Success(CBigInt(new BigInteger("-8000", 16)))), - (-26248.toShort, Success(CBigInt(new BigInteger("-6688", 16)))), - (-1.toShort, Success(CBigInt(new BigInteger("-1", 16)))), - (0.toShort, Success(CBigInt(new BigInteger("0", 16)))), - (1.toShort, Success(CBigInt(new BigInteger("1", 16)))), - (22845.toShort, Success(CBigInt(new BigInteger("593d", 16)))), - (32767.toShort, Success(CBigInt(new BigInteger("7fff", 16)))) - ), + verifyCases( + { + def success(v: BigInt) = Success(Expected(v, 35932)) + Seq( + (-32768.toShort, success(CBigInt(new BigInteger("-8000", 16)))), + (-26248.toShort, success(CBigInt(new BigInteger("-6688", 16)))), + (-1.toShort, success(CBigInt(new BigInteger("-1", 16)))), + (0.toShort, success(CBigInt(new BigInteger("0", 16)))), + (1.toShort, success(CBigInt(new BigInteger("1", 16)))), + (22845.toShort, success(CBigInt(new BigInteger("593d", 16)))), + (32767.toShort, success(CBigInt(new BigInteger("7fff", 16)))) + ) + }, existingFeature((x: Short) => x.toBigInt, "{ (x: Short) => x.toBigInt }", FuncValue(Vector((1, SShort)), Upcast(ValUse(1, SShort), SBigInt)))) val n = ExactNumeric.ShortIsExactNumeric - testCases( - Seq( - ((-32768.toShort, 1.toShort), Failure(new ArithmeticException("Short overflow"))), - ((-32768.toShort, 4006.toShort), Failure(new ArithmeticException("Short overflow"))), - ((-21384.toShort, 0.toShort), Failure(new ArithmeticException("/ by zero"))), - ((-19027.toShort, 6073.toShort), Failure(new ArithmeticException("Short overflow"))), - ((-16800.toShort, 32767.toShort), Failure(new ArithmeticException("Short overflow"))), - ((-1.toShort, -30005.toShort), Success((-30006.toShort, (30004.toShort, (30005.toShort, (0.toShort, -1.toShort)))))), - ((-1.toShort, 0.toShort), Failure(new ArithmeticException("/ by zero"))), - ((0.toShort, -1.toShort), Success((-1.toShort, (1.toShort, (0.toShort, (0.toShort, 0.toShort)))))), - ((0.toShort, 0.toShort), Failure(new ArithmeticException("/ by zero"))), - ((0.toShort, 1.toShort), Success((1.toShort, (-1.toShort, (0.toShort, (0.toShort, 0.toShort)))))), - ((0.toShort, 25105.toShort), Success((25105.toShort, (-25105.toShort, (0.toShort, (0.toShort, 0.toShort)))))), - ((1.toShort, -32768.toShort), Failure(new ArithmeticException("Short overflow"))), - ((1.toShort, -1.toShort), Success((0.toShort, (2.toShort, (-1.toShort, (-1.toShort, 0.toShort)))))), - ((1.toShort, 0.toShort), Failure(new ArithmeticException("/ by zero"))), - ((605.toShort, 7698.toShort), Failure(new ArithmeticException("Short overflow"))), - ((5094.toShort, -32768.toShort), Failure(new ArithmeticException("Short overflow"))), - ((5350.toShort, -1.toShort), Success((5349.toShort, (5351.toShort, (-5350.toShort, (-5350.toShort, 0.toShort)))))), - ((8115.toShort, -32768.toShort), Failure(new ArithmeticException("Short overflow"))), - ((14217.toShort, 32767.toShort), Failure(new ArithmeticException("Short overflow"))), - ((16223.toShort, -11686.toShort), Failure(new ArithmeticException("Short overflow"))), - ((16989.toShort, 1.toShort), Success((16990.toShort, (16988.toShort, (16989.toShort, (16989.toShort, 0.toShort)))))), - ((20397.toShort, -4450.toShort), Failure(new ArithmeticException("Short overflow"))), - ((20488.toShort, 1.toShort), Success((20489.toShort, (20487.toShort, (20488.toShort, (20488.toShort, 0.toShort)))))), - ((32767.toShort, -32768.toShort), Failure(new ArithmeticException("Short overflow"))), - ((32767.toShort, -13423.toShort), Failure(new ArithmeticException("Short overflow"))), - ((32767.toShort, 32767.toShort), Failure(new ArithmeticException("Short overflow"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 39654)) + Seq( + ((-32768.toShort, 1.toShort), Failure(new ArithmeticException("Short overflow"))), + ((-32768.toShort, 4006.toShort), Failure(new ArithmeticException("Short overflow"))), + ((-21384.toShort, 0.toShort), Failure(new ArithmeticException("/ by zero"))), + ((-19027.toShort, 6073.toShort), Failure(new ArithmeticException("Short overflow"))), + ((-16800.toShort, 32767.toShort), Failure(new ArithmeticException("Short overflow"))), + ((-1.toShort, -30005.toShort), success((-30006.toShort, (30004.toShort, (30005.toShort, (0.toShort, -1.toShort)))))), + ((-1.toShort, 0.toShort), Failure(new ArithmeticException("/ by zero"))), + ((0.toShort, -1.toShort), success((-1.toShort, (1.toShort, (0.toShort, (0.toShort, 0.toShort)))))), + ((0.toShort, 0.toShort), Failure(new ArithmeticException("/ by zero"))), + ((0.toShort, 1.toShort), success((1.toShort, (-1.toShort, (0.toShort, (0.toShort, 0.toShort)))))), + ((0.toShort, 25105.toShort), success((25105.toShort, (-25105.toShort, (0.toShort, (0.toShort, 0.toShort)))))), + ((1.toShort, -32768.toShort), Failure(new ArithmeticException("Short overflow"))), + ((1.toShort, -1.toShort), success((0.toShort, (2.toShort, (-1.toShort, (-1.toShort, 0.toShort)))))), + ((1.toShort, 0.toShort), Failure(new ArithmeticException("/ by zero"))), + ((605.toShort, 7698.toShort), Failure(new ArithmeticException("Short overflow"))), + ((5094.toShort, -32768.toShort), Failure(new ArithmeticException("Short overflow"))), + ((5350.toShort, -1.toShort), success((5349.toShort, (5351.toShort, (-5350.toShort, (-5350.toShort, 0.toShort)))))), + ((8115.toShort, -32768.toShort), Failure(new ArithmeticException("Short overflow"))), + ((14217.toShort, 32767.toShort), Failure(new ArithmeticException("Short overflow"))), + ((16223.toShort, -11686.toShort), Failure(new ArithmeticException("Short overflow"))), + ((16989.toShort, 1.toShort), success((16990.toShort, (16988.toShort, (16989.toShort, (16989.toShort, 0.toShort)))))), + ((20397.toShort, -4450.toShort), Failure(new ArithmeticException("Short overflow"))), + ((20488.toShort, 1.toShort), success((20489.toShort, (20487.toShort, (20488.toShort, (20488.toShort, 0.toShort)))))), + ((32767.toShort, -32768.toShort), Failure(new ArithmeticException("Short overflow"))), + ((32767.toShort, -13423.toShort), Failure(new ArithmeticException("Short overflow"))), + ((32767.toShort, 32767.toShort), Failure(new ArithmeticException("Short overflow"))) + ) + }, existingFeature( { (x: (Short, Short)) => val a = x._1; val b = x._2 @@ -746,107 +786,125 @@ class SigmaDslSpec extends SigmaDslTesting { suite => SInt.upcast(0) shouldBe 0 // boundary test case SInt.downcast(0) shouldBe 0 // boundary test case - testCases( - Seq( - (Int.MinValue, Failure(new ArithmeticException("Byte overflow"))), - (-2014394379, Failure(new ArithmeticException("Byte overflow"))), - (Byte.MinValue.toInt, Success(Byte.MinValue)), - (-1, Success(-1.toByte)), - (0, Success(0.toByte)), - (1, Success(1.toByte)), - (Byte.MaxValue.toInt, Success(Byte.MaxValue)), - (181686429, Failure(new ArithmeticException("Byte overflow"))), - (Int.MaxValue, Failure(new ArithmeticException("Byte overflow"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35976)) + Seq( + (Int.MinValue, Failure(new ArithmeticException("Byte overflow"))), + (-2014394379, Failure(new ArithmeticException("Byte overflow"))), + (Byte.MinValue.toInt, success(Byte.MinValue)), + (-1, success(-1.toByte)), + (0, success(0.toByte)), + (1, success(1.toByte)), + (Byte.MaxValue.toInt, success(Byte.MaxValue)), + (181686429, Failure(new ArithmeticException("Byte overflow"))), + (Int.MaxValue, Failure(new ArithmeticException("Byte overflow"))) + ) + }, existingFeature((x: Int) => x.toByteExact, "{ (x: Int) => x.toByte }", FuncValue(Vector((1, SInt)), Downcast(ValUse(1, SInt), SByte)))) - testCases( - Seq( - (Int.MinValue, Failure(new ArithmeticException("Short overflow"))), - (Short.MinValue - 1, Failure(new ArithmeticException("Short overflow"))), - (Short.MinValue.toInt, Success(Short.MinValue)), - (-1, Success(-1.toShort)), - (0, Success(0.toShort)), - (1, Success(1.toShort)), - (Short.MaxValue.toInt, Success(Short.MaxValue)), - (Short.MaxValue + 1, Failure(new ArithmeticException("Short overflow"))), - (Int.MaxValue, Failure(new ArithmeticException("Short overflow"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35976)) + Seq( + (Int.MinValue, Failure(new ArithmeticException("Short overflow"))), + (Short.MinValue - 1, Failure(new ArithmeticException("Short overflow"))), + (Short.MinValue.toInt, success(Short.MinValue)), + (-1, success(-1.toShort)), + (0, success(0.toShort)), + (1, success(1.toShort)), + (Short.MaxValue.toInt, success(Short.MaxValue)), + (Short.MaxValue + 1, Failure(new ArithmeticException("Short overflow"))), + (Int.MaxValue, Failure(new ArithmeticException("Short overflow"))) + ) + }, existingFeature((x: Int) => x.toShortExact, "{ (x: Int) => x.toShort }", FuncValue(Vector((1, SInt)), Downcast(ValUse(1, SInt), SShort)))) - testCases( - Seq( - (Int.MinValue, Success(Int.MinValue)), - (-1, Success(-1)), - (0, Success(0)), - (1, Success(1)), - (Int.MaxValue, Success(Int.MaxValue)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35798)) + Seq( + (Int.MinValue, success(Int.MinValue)), + (-1, success(-1)), + (0, success(0)), + (1, success(1)), + (Int.MaxValue, success(Int.MaxValue)) + ) + }, existingFeature((x: Int) => x.toInt, "{ (x: Int) => x.toInt }", FuncValue(Vector((1, SInt)), ValUse(1, SInt)))) - testCases( - Seq( - (Int.MinValue, Success(Int.MinValue.toLong)), - (-1, Success(-1L)), - (0, Success(0L)), - (1, Success(1L)), - (Int.MaxValue, Success(Int.MaxValue.toLong)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35902)) + Seq( + (Int.MinValue, success(Int.MinValue.toLong)), + (-1, success(-1L)), + (0, success(0L)), + (1, success(1L)), + (Int.MaxValue, success(Int.MaxValue.toLong)) + ) + }, existingFeature((x: Int) => x.toLong, "{ (x: Int) => x.toLong }", FuncValue(Vector((1, SInt)), Upcast(ValUse(1, SInt), SLong)))) - testCases( - Seq( - (Int.MinValue, Success(CBigInt(new BigInteger("-80000000", 16)))), - (-1937187314, Success(CBigInt(new BigInteger("-737721f2", 16)))), - (-1, Success(CBigInt(new BigInteger("-1", 16)))), - (0, Success(CBigInt(new BigInteger("0", 16)))), - (1, Success(CBigInt(new BigInteger("1", 16)))), - (1542171288, Success(CBigInt(new BigInteger("5bebaa98", 16)))), - (Int.MaxValue, Success(CBigInt(new BigInteger("7fffffff", 16)))) - ), + verifyCases( + { + def success(v: BigInt) = Success(Expected(v, 35932)) + Seq( + (Int.MinValue, success(CBigInt(new BigInteger("-80000000", 16)))), + (-1937187314, success(CBigInt(new BigInteger("-737721f2", 16)))), + (-1, success(CBigInt(new BigInteger("-1", 16)))), + (0, success(CBigInt(new BigInteger("0", 16)))), + (1, success(CBigInt(new BigInteger("1", 16)))), + (1542171288, success(CBigInt(new BigInteger("5bebaa98", 16)))), + (Int.MaxValue, success(CBigInt(new BigInteger("7fffffff", 16)))) + ) + }, existingFeature((x: Int) => x.toBigInt, "{ (x: Int) => x.toBigInt }", FuncValue(Vector((1, SInt)), Upcast(ValUse(1, SInt), SBigInt)))) val n = ExactNumeric.IntIsExactNumeric - testCases( - Seq( - ((Int.MinValue, 449583993), Failure(new ArithmeticException("integer overflow"))), - ((-1589633733, 2147483647), Failure(new ArithmeticException("integer overflow"))), - ((-1585471506, -1), Success((-1585471507, (-1585471505, (1585471506, (1585471506, 0)))))), - ((-1569005179, 1230236634), Failure(new ArithmeticException("integer overflow"))), - ((-1493733356, -1319619597), Failure(new ArithmeticException("integer overflow"))), - ((-1100263120, -880052091), Failure(new ArithmeticException("integer overflow"))), - ((-1055955857, 309147303), Failure(new ArithmeticException("integer overflow"))), - ((-569807371, 0), Failure(new ArithmeticException("/ by zero"))), - ((-522264843, 2147483647), Failure(new ArithmeticException("integer overflow"))), - ((-109552389, 0), Failure(new ArithmeticException("/ by zero"))), - ((-1, -2147483648), Failure(new ArithmeticException("integer overflow"))), - ((-1, -1), Success((-2, (0, (1, (1, 0)))))), - ((-1, 0), Failure(new ArithmeticException("/ by zero"))), - ((0, -2147483648), Failure(new ArithmeticException("integer overflow"))), - ((1, -1525049432), Success((-1525049431, (1525049433, (-1525049432, (0, 1)))))), - ((1, 0), Failure(new ArithmeticException("/ by zero"))), - ((1, 805353746), Success((805353747, (-805353745, (805353746, (0, 1)))))), - ((1, 2147483647), Failure(new ArithmeticException("integer overflow"))), - ((475797978, 0), Failure(new ArithmeticException("/ by zero"))), - ((782343922, -1448560539), Failure(new ArithmeticException("integer overflow"))), - ((928769361, 542647292), Failure(new ArithmeticException("integer overflow"))), - ((1568062151, 0), Failure(new ArithmeticException("/ by zero"))), - ((1698252401, -1), Success((1698252400, (1698252402, (-1698252401, (-1698252401, 0)))))), - ((1949795740, -1575667037), Failure(new ArithmeticException("integer overflow"))), - ((Int.MaxValue, -1), Failure(new ArithmeticException("integer overflow"))), - ((Int.MaxValue, 1), Failure(new ArithmeticException("integer overflow"))), - ((Int.MaxValue, 1738276576), Failure(new ArithmeticException("integer overflow"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 39654)) + Seq( + ((Int.MinValue, 449583993), Failure(new ArithmeticException("integer overflow"))), + ((-1589633733, 2147483647), Failure(new ArithmeticException("integer overflow"))), + ((-1585471506, -1), success((-1585471507, (-1585471505, (1585471506, (1585471506, 0)))))), + ((-1569005179, 1230236634), Failure(new ArithmeticException("integer overflow"))), + ((-1493733356, -1319619597), Failure(new ArithmeticException("integer overflow"))), + ((-1100263120, -880052091), Failure(new ArithmeticException("integer overflow"))), + ((-1055955857, 309147303), Failure(new ArithmeticException("integer overflow"))), + ((-569807371, 0), Failure(new ArithmeticException("/ by zero"))), + ((-522264843, 2147483647), Failure(new ArithmeticException("integer overflow"))), + ((-109552389, 0), Failure(new ArithmeticException("/ by zero"))), + ((-1, -2147483648), Failure(new ArithmeticException("integer overflow"))), + ((-1, -1), success((-2, (0, (1, (1, 0)))))), + ((-1, 0), Failure(new ArithmeticException("/ by zero"))), + ((0, -2147483648), Failure(new ArithmeticException("integer overflow"))), + ((1, -1525049432), success((-1525049431, (1525049433, (-1525049432, (0, 1)))))), + ((1, 0), Failure(new ArithmeticException("/ by zero"))), + ((1, 805353746), success((805353747, (-805353745, (805353746, (0, 1)))))), + ((1, 2147483647), Failure(new ArithmeticException("integer overflow"))), + ((475797978, 0), Failure(new ArithmeticException("/ by zero"))), + ((782343922, -1448560539), Failure(new ArithmeticException("integer overflow"))), + ((928769361, 542647292), Failure(new ArithmeticException("integer overflow"))), + ((1568062151, 0), Failure(new ArithmeticException("/ by zero"))), + ((1698252401, -1), success((1698252400, (1698252402, (-1698252401, (-1698252401, 0)))))), + ((1949795740, -1575667037), Failure(new ArithmeticException("integer overflow"))), + ((Int.MaxValue, -1), Failure(new ArithmeticException("integer overflow"))), + ((Int.MaxValue, 1), Failure(new ArithmeticException("integer overflow"))), + ((Int.MaxValue, 1738276576), Failure(new ArithmeticException("integer overflow"))) + ) + }, existingFeature( { (x: (Int, Int)) => val a = x._1; val b = x._2 @@ -933,109 +991,127 @@ class SigmaDslSpec extends SigmaDslTesting { suite => SLong.upcast(0L) shouldBe 0L // boundary test case SLong.downcast(0L) shouldBe 0L // boundary test case - testCases( - Seq( - (Long.MinValue, Failure(new ArithmeticException("Byte overflow"))), - (Byte.MinValue.toLong - 1, Failure(new ArithmeticException("Byte overflow"))), - (Byte.MinValue.toLong, Success(Byte.MinValue)), - (-1L, Success(-1.toByte)), - (0L, Success(0.toByte)), - (1L, Success(1.toByte)), - (Byte.MaxValue.toLong, Success(Byte.MaxValue)), - (Byte.MaxValue.toLong + 1, Failure(new ArithmeticException("Byte overflow"))), - (Long.MinValue, Failure(new ArithmeticException("Byte overflow"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35976)) + Seq( + (Long.MinValue, Failure(new ArithmeticException("Byte overflow"))), + (Byte.MinValue.toLong - 1, Failure(new ArithmeticException("Byte overflow"))), + (Byte.MinValue.toLong, success(Byte.MinValue)), + (-1L, success(-1.toByte)), + (0L, success(0.toByte)), + (1L, success(1.toByte)), + (Byte.MaxValue.toLong, success(Byte.MaxValue)), + (Byte.MaxValue.toLong + 1, Failure(new ArithmeticException("Byte overflow"))), + (Long.MinValue, Failure(new ArithmeticException("Byte overflow"))) + ) + }, existingFeature((x: Long) => x.toByteExact, "{ (x: Long) => x.toByte }", FuncValue(Vector((1, SLong)), Downcast(ValUse(1, SLong), SByte)))) - testCases( - Seq( - (Long.MinValue, Failure(new ArithmeticException("Short overflow"))), - (Short.MinValue.toLong - 1, Failure(new ArithmeticException("Short overflow"))), - (Short.MinValue.toLong, Success(Short.MinValue)), - (-1L, Success(-1.toShort)), - (0L, Success(0.toShort)), - (1L, Success(1.toShort)), - (Short.MaxValue.toLong, Success(Short.MaxValue)), - (Short.MaxValue.toLong + 1, Failure(new ArithmeticException("Short overflow"))), - (Long.MinValue, Failure(new ArithmeticException("Short overflow"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35976)) + Seq( + (Long.MinValue, Failure(new ArithmeticException("Short overflow"))), + (Short.MinValue.toLong - 1, Failure(new ArithmeticException("Short overflow"))), + (Short.MinValue.toLong, success(Short.MinValue)), + (-1L, success(-1.toShort)), + (0L, success(0.toShort)), + (1L, success(1.toShort)), + (Short.MaxValue.toLong, success(Short.MaxValue)), + (Short.MaxValue.toLong + 1, Failure(new ArithmeticException("Short overflow"))), + (Long.MinValue, Failure(new ArithmeticException("Short overflow"))) + ) + }, existingFeature((x: Long) => x.toShortExact, "{ (x: Long) => x.toShort }", FuncValue(Vector((1, SLong)), Downcast(ValUse(1, SLong), SShort)))) - testCases( - Seq( - (Long.MinValue, Failure(new ArithmeticException("Int overflow"))), - (Int.MinValue.toLong - 1, Failure(new ArithmeticException("Int overflow"))), - (Int.MinValue.toLong, Success(Int.MinValue)), - (-1L, Success(-1.toInt)), - (0L, Success(0.toInt)), - (1L, Success(1.toInt)), - (Int.MaxValue.toLong, Success(Int.MaxValue)), - (Int.MaxValue.toLong + 1, Failure(new ArithmeticException("Int overflow"))), - (Long.MinValue, Failure(new ArithmeticException("Int overflow"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35976)) + Seq( + (Long.MinValue, Failure(new ArithmeticException("Int overflow"))), + (Int.MinValue.toLong - 1, Failure(new ArithmeticException("Int overflow"))), + (Int.MinValue.toLong, success(Int.MinValue)), + (-1L, success(-1.toInt)), + (0L, success(0.toInt)), + (1L, success(1.toInt)), + (Int.MaxValue.toLong, success(Int.MaxValue)), + (Int.MaxValue.toLong + 1, Failure(new ArithmeticException("Int overflow"))), + (Long.MinValue, Failure(new ArithmeticException("Int overflow"))) + ) + }, existingFeature((x: Long) => x.toIntExact, "{ (x: Long) => x.toInt }", FuncValue(Vector((1, SLong)), Downcast(ValUse(1, SLong), SInt)))) - testCases( - Seq( - (Long.MinValue, Success(Long.MinValue)), - (-1L, Success(-1L)), - (0L, Success(0L)), - (1L, Success(1L)), - (Long.MaxValue, Success(Long.MaxValue)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35798)) + Seq( + (Long.MinValue, success(Long.MinValue)), + (-1L, success(-1L)), + (0L, success(0L)), + (1L, success(1L)), + (Long.MaxValue, success(Long.MaxValue)) + ) + }, existingFeature((x: Long) => x.toLong, "{ (x: Long) => x.toLong }", FuncValue(Vector((1, SLong)), ValUse(1, SLong)))) - testCases( - Seq( - (Long.MinValue, Success(CBigInt(new BigInteger("-8000000000000000", 16)))), - (-1074651039980347209L, Success(CBigInt(new BigInteger("-ee9ed6d57885f49", 16)))), - (-1L, Success(CBigInt(new BigInteger("-1", 16)))), - (0L, Success(CBigInt(new BigInteger("0", 16)))), - (1L, Success(CBigInt(new BigInteger("1", 16)))), - (1542942726564696512L, Success(CBigInt(new BigInteger("1569a23c25a951c0", 16)))), - (Long.MaxValue, Success(CBigInt(new BigInteger("7fffffffffffffff", 16)))) - ), + verifyCases( + { + def success(v: BigInt) = Success(Expected(v, 35932)) + Seq( + (Long.MinValue, success(CBigInt(new BigInteger("-8000000000000000", 16)))), + (-1074651039980347209L, success(CBigInt(new BigInteger("-ee9ed6d57885f49", 16)))), + (-1L, success(CBigInt(new BigInteger("-1", 16)))), + (0L, success(CBigInt(new BigInteger("0", 16)))), + (1L, success(CBigInt(new BigInteger("1", 16)))), + (1542942726564696512L, success(CBigInt(new BigInteger("1569a23c25a951c0", 16)))), + (Long.MaxValue, success(CBigInt(new BigInteger("7fffffffffffffff", 16)))) + ) + }, existingFeature((x: Long) => x.toBigInt, "{ (x: Long) => x.toBigInt }", FuncValue(Vector((1, SLong)), Upcast(ValUse(1, SLong), SBigInt)))) val n = ExactNumeric.LongIsExactNumeric - testCases( - Seq( - ((Long.MinValue, -4677100190307931395L), Failure(new ArithmeticException("long overflow"))), - ((Long.MinValue, -1L), Failure(new ArithmeticException("long overflow"))), - ((Long.MinValue, 1L), Failure(new ArithmeticException("long overflow"))), - ((-9223372036854775808L, 0L), Failure(new ArithmeticException("/ by zero"))), - ((-5828066432064138816L, 9105034716270510411L), Failure(new ArithmeticException("long overflow"))), - ((-4564956247298949325L, -1L), Success( - (-4564956247298949326L, (-4564956247298949324L, (4564956247298949325L, (4564956247298949325L, 0L)))) - )), - ((-1499553565058783253L, -3237683216870282569L), Failure(new ArithmeticException("long overflow"))), - ((-1368457031689886112L, 9223372036854775807L), Failure(new ArithmeticException("long overflow"))), - ((-1L, -4354407074688367443L), Success((-4354407074688367444L, (4354407074688367442L, (4354407074688367443L, (0L, -1L)))))), - ((-1L, -1L), Success((-2L, (0L, (1L, (1L, 0L)))))), - ((-1L, 5665019549505434695L), Success((5665019549505434694L, (-5665019549505434696L, (-5665019549505434695L, (0L, -1L)))))), - ((0L, -1L), Success((-1L, (1L, (0L, (0L, 0L)))))), - ((0L, 0L), Failure(new ArithmeticException("/ by zero"))), - ((0L, 2112386634269044172L), Success((2112386634269044172L, (-2112386634269044172L, (0L, (0L, 0L)))))), - ((2254604056782701370L, -5878231674026236574L), Failure(new ArithmeticException("long overflow"))), - ((2903872550238813643L, 1L), Success( - (2903872550238813644L, (2903872550238813642L, (2903872550238813643L, (2903872550238813643L, 0L)))) - )), - ((5091129735284641762L, -427673944382373638L), Failure(new ArithmeticException("long overflow"))), - ((6029085020194630780L, 2261786144956037939L), Failure(new ArithmeticException("long overflow"))), - ((8126382074515995418L, -4746652047588907829L), Failure(new ArithmeticException("long overflow"))), - ((Long.MaxValue, 1L), Failure(new ArithmeticException("long overflow"))), - ((Long.MaxValue, -1L), Failure(new ArithmeticException("long overflow"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 39654)) + Seq( + ((Long.MinValue, -4677100190307931395L), Failure(new ArithmeticException("long overflow"))), + ((Long.MinValue, -1L), Failure(new ArithmeticException("long overflow"))), + ((Long.MinValue, 1L), Failure(new ArithmeticException("long overflow"))), + ((-9223372036854775808L, 0L), Failure(new ArithmeticException("/ by zero"))), + ((-5828066432064138816L, 9105034716270510411L), Failure(new ArithmeticException("long overflow"))), + ((-4564956247298949325L, -1L), success( + (-4564956247298949326L, (-4564956247298949324L, (4564956247298949325L, (4564956247298949325L, 0L)))) + )), + ((-1499553565058783253L, -3237683216870282569L), Failure(new ArithmeticException("long overflow"))), + ((-1368457031689886112L, 9223372036854775807L), Failure(new ArithmeticException("long overflow"))), + ((-1L, -4354407074688367443L), success((-4354407074688367444L, (4354407074688367442L, (4354407074688367443L, (0L, -1L)))))), + ((-1L, -1L), success((-2L, (0L, (1L, (1L, 0L)))))), + ((-1L, 5665019549505434695L), success((5665019549505434694L, (-5665019549505434696L, (-5665019549505434695L, (0L, -1L)))))), + ((0L, -1L), success((-1L, (1L, (0L, (0L, 0L)))))), + ((0L, 0L), Failure(new ArithmeticException("/ by zero"))), + ((0L, 2112386634269044172L), success((2112386634269044172L, (-2112386634269044172L, (0L, (0L, 0L)))))), + ((2254604056782701370L, -5878231674026236574L), Failure(new ArithmeticException("long overflow"))), + ((2903872550238813643L, 1L), success( + (2903872550238813644L, (2903872550238813642L, (2903872550238813643L, (2903872550238813643L, 0L)))) + )), + ((5091129735284641762L, -427673944382373638L), Failure(new ArithmeticException("long overflow"))), + ((6029085020194630780L, 2261786144956037939L), Failure(new ArithmeticException("long overflow"))), + ((8126382074515995418L, -4746652047588907829L), Failure(new ArithmeticException("long overflow"))), + ((Long.MaxValue, 1L), Failure(new ArithmeticException("long overflow"))), + ((Long.MaxValue, -1L), Failure(new ArithmeticException("long overflow"))) + ) + }, existingFeature( { (x: (Long, Long)) => val a = x._1; val b = x._2 @@ -1120,85 +1196,91 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("BigInt methods equivalence") { - testCases( - Seq( - (CBigInt(new BigInteger("-85102d7f884ca0e8f56193b46133acaf7e4681e1757d03f191ae4f445c8e0", 16)), Success( - CBigInt(new BigInteger("-85102d7f884ca0e8f56193b46133acaf7e4681e1757d03f191ae4f445c8e0", 16)) - )), - (CBigInt(new BigInteger("-8000000000000000", 16)), Success(CBigInt(new BigInteger("-8000000000000000", 16)))), - (CBigInt(new BigInteger("-1", 16)), Success(CBigInt(new BigInteger("-1", 16)))), - (CBigInt(new BigInteger("0", 16)), Success(CBigInt(new BigInteger("0", 16)))), - (CBigInt(new BigInteger("1", 16)), Success(CBigInt(new BigInteger("1", 16)))), - (CBigInt(new BigInteger("7fffffffffffffff", 16)), Success(CBigInt(new BigInteger("7fffffffffffffff", 16)))), - (CBigInt(new BigInteger("bdd56c22eb3eace8bc4e1c38c65dfdb2e4ffdcf421ae78c36b93b9ff37dc0", 16)), Success( - CBigInt(new BigInteger("bdd56c22eb3eace8bc4e1c38c65dfdb2e4ffdcf421ae78c36b93b9ff37dc0", 16)) - )) - ), + verifyCases( + { + def success(v: BigInt) = Success(Expected(v, 35798)) + Seq( + (CBigInt(new BigInteger("-85102d7f884ca0e8f56193b46133acaf7e4681e1757d03f191ae4f445c8e0", 16)), success( + CBigInt(new BigInteger("-85102d7f884ca0e8f56193b46133acaf7e4681e1757d03f191ae4f445c8e0", 16)) + )), + (CBigInt(new BigInteger("-8000000000000000", 16)), success(CBigInt(new BigInteger("-8000000000000000", 16)))), + (CBigInt(new BigInteger("-1", 16)), success(CBigInt(new BigInteger("-1", 16)))), + (CBigInt(new BigInteger("0", 16)), success(CBigInt(new BigInteger("0", 16)))), + (CBigInt(new BigInteger("1", 16)), success(CBigInt(new BigInteger("1", 16)))), + (CBigInt(new BigInteger("7fffffffffffffff", 16)), success(CBigInt(new BigInteger("7fffffffffffffff", 16)))), + (CBigInt(new BigInteger("bdd56c22eb3eace8bc4e1c38c65dfdb2e4ffdcf421ae78c36b93b9ff37dc0", 16)), success( + CBigInt(new BigInteger("bdd56c22eb3eace8bc4e1c38c65dfdb2e4ffdcf421ae78c36b93b9ff37dc0", 16)) + )) + ) + }, existingFeature((x: BigInt) => x, "{ (x: BigInt) => x.toBigInt }", FuncValue(Vector((1, SBigInt)), ValUse(1, SBigInt)))) val n = NumericOps.BigIntIsExactNumeric - testCases( - Seq( - ((CBigInt(new BigInteger("-8683d1cd99d5fcf0e6eff6295c285c36526190e13dbde008c49e5ae6fddc1c", 16)), - CBigInt(new BigInteger("-2ef55db3f245feddacf0182e299dd", 16))), - Failure(new ArithmeticException("BigInteger out of 256 bit range"))), - - ((CBigInt(new BigInteger("-68e1136872f98fb0245ec5aa4bef46e16273e860746c892", 16)), - CBigInt(new BigInteger("-352aaa769b41a327", 16))), - Failure(new ArithmeticException("BigInteger: modulus not positive"))), - - ((CBigInt(new BigInteger("-39fc00ebf09080cbd8408dd38c4b7490bea533447047140", 16)), - CBigInt(new BigInteger("31de9e96177dbd39", 16))), - Success(( - CBigInt(new BigInteger("-39fc00ebf09080cbd8408dd38c4b748da0bb49e2f86b407", 16)), - (CBigInt(new BigInteger("-39fc00ebf09080cbd8408dd38c4b7493dc8f1ca5e822e79", 16)), - (CBigInt(new BigInteger("-b4ba8a17d328dac74ef014d7be35597a1259f8b16f0ff1c9820dea23d97740", 16)), - (CBigInt(new BigInteger("-129a8045376e104f0d3771b6c2c128fc", 16)), - CBigInt(new BigInteger("12fe89836fc97815", 16)))))) )), - - ((CBigInt(new BigInteger("-8000000000000000", 16)), CBigInt(new BigInteger("8000000000000000", 16))), - Success(( - CBigInt(new BigInteger("0", 16)), - (CBigInt(new BigInteger("-10000000000000000", 16)), - (CBigInt(new BigInteger("-40000000000000000000000000000000", 16)), - (CBigInt(new BigInteger("-1", 16)), CBigInt(new BigInteger("0", 16)))))) )), - - ((CBigInt(new BigInteger("-47dede8d3e4804bb", 16)), CBigInt(new BigInteger("-388828eb6dfce683", 16))), - Failure(new ArithmeticException("BigInteger: modulus not positive"))), - - ((CBigInt(new BigInteger("-4fde491150ea00d", 16)), CBigInt(new BigInteger("-80000001", 16))), - Failure(new ArithmeticException("BigInteger: modulus not positive"))), - - ((CBigInt(new BigInteger("-80000001", 16)), CBigInt(new BigInteger("-80000001", 16))), - Failure(new ArithmeticException("BigInteger: modulus not positive"))), - - ((CBigInt(new BigInteger("0", 16)), CBigInt(new BigInteger("-8000000000000000", 16))), - Failure(new ArithmeticException("BigInteger: modulus not positive"))), - - ((CBigInt(new BigInteger("0", 16)), CBigInt(new BigInteger("0", 16))), - Failure(new ArithmeticException("BigInteger divide by zero"))), - - ((CBigInt(new BigInteger("1", 16)), - CBigInt(new BigInteger("-86063f66e06d6d535c95862cd506309a95d10102422fee", 16))), - Failure(new ArithmeticException("BigInteger: modulus not positive"))), - - ((CBigInt(new BigInteger("80000000", 16)), CBigInt(new BigInteger("4e592ce5b544b8f7a91f97ec9ea2f2c3660111360297a4", 16))), - Success(( - CBigInt(new BigInteger("4e592ce5b544b8f7a91f97ec9ea2f2c3660111b60297a4", 16)), - (CBigInt(new BigInteger("-4e592ce5b544b8f7a91f97ec9ea2f2c3660110b60297a4", 16)), - (CBigInt(new BigInteger("272c9672daa25c7bd48fcbf64f517961b300889b014bd200000000", 16)), - (CBigInt(new BigInteger("0", 16)), CBigInt(new BigInteger("80000000", 16)))))) )), - - ((CBigInt(new BigInteger("3d31398dc4783303", 16)), - CBigInt(new BigInteger("-37b381db4e6e927e202a2a421d5a09ca", 16))), - Failure(new ArithmeticException("BigInteger: modulus not positive"))), - - ((CBigInt(new BigInteger("5524814a26357cb71488b6fb26af2d3", 16)), - CBigInt(new BigInteger("c413b7d975a9972427f46996299fe57cfe79479ac954a7", 16))), - Failure(new ArithmeticException("BigInteger out of 256 bit range"))) - ), + verifyCases( + { + def success(v: (BigInt, (BigInt, (BigInt, (BigInt, BigInt))))) = Success(Expected(v, 39774)) + Seq( + ((CBigInt(new BigInteger("-8683d1cd99d5fcf0e6eff6295c285c36526190e13dbde008c49e5ae6fddc1c", 16)), + CBigInt(new BigInteger("-2ef55db3f245feddacf0182e299dd", 16))), + Failure(new ArithmeticException("BigInteger out of 256 bit range"))), + + ((CBigInt(new BigInteger("-68e1136872f98fb0245ec5aa4bef46e16273e860746c892", 16)), + CBigInt(new BigInteger("-352aaa769b41a327", 16))), + Failure(new ArithmeticException("BigInteger: modulus not positive"))), + + ((CBigInt(new BigInteger("-39fc00ebf09080cbd8408dd38c4b7490bea533447047140", 16)), + CBigInt(new BigInteger("31de9e96177dbd39", 16))), + success(( + CBigInt(new BigInteger("-39fc00ebf09080cbd8408dd38c4b748da0bb49e2f86b407", 16)), + (CBigInt(new BigInteger("-39fc00ebf09080cbd8408dd38c4b7493dc8f1ca5e822e79", 16)), + (CBigInt(new BigInteger("-b4ba8a17d328dac74ef014d7be35597a1259f8b16f0ff1c9820dea23d97740", 16)), + (CBigInt(new BigInteger("-129a8045376e104f0d3771b6c2c128fc", 16)), + CBigInt(new BigInteger("12fe89836fc97815", 16)))))) )), + + ((CBigInt(new BigInteger("-8000000000000000", 16)), CBigInt(new BigInteger("8000000000000000", 16))), + success(( + CBigInt(new BigInteger("0", 16)), + (CBigInt(new BigInteger("-10000000000000000", 16)), + (CBigInt(new BigInteger("-40000000000000000000000000000000", 16)), + (CBigInt(new BigInteger("-1", 16)), CBigInt(new BigInteger("0", 16)))))) )), + + ((CBigInt(new BigInteger("-47dede8d3e4804bb", 16)), CBigInt(new BigInteger("-388828eb6dfce683", 16))), + Failure(new ArithmeticException("BigInteger: modulus not positive"))), + + ((CBigInt(new BigInteger("-4fde491150ea00d", 16)), CBigInt(new BigInteger("-80000001", 16))), + Failure(new ArithmeticException("BigInteger: modulus not positive"))), + + ((CBigInt(new BigInteger("-80000001", 16)), CBigInt(new BigInteger("-80000001", 16))), + Failure(new ArithmeticException("BigInteger: modulus not positive"))), + + ((CBigInt(new BigInteger("0", 16)), CBigInt(new BigInteger("-8000000000000000", 16))), + Failure(new ArithmeticException("BigInteger: modulus not positive"))), + + ((CBigInt(new BigInteger("0", 16)), CBigInt(new BigInteger("0", 16))), + Failure(new ArithmeticException("BigInteger divide by zero"))), + + ((CBigInt(new BigInteger("1", 16)), + CBigInt(new BigInteger("-86063f66e06d6d535c95862cd506309a95d10102422fee", 16))), + Failure(new ArithmeticException("BigInteger: modulus not positive"))), + + ((CBigInt(new BigInteger("80000000", 16)), CBigInt(new BigInteger("4e592ce5b544b8f7a91f97ec9ea2f2c3660111360297a4", 16))), + success(( + CBigInt(new BigInteger("4e592ce5b544b8f7a91f97ec9ea2f2c3660111b60297a4", 16)), + (CBigInt(new BigInteger("-4e592ce5b544b8f7a91f97ec9ea2f2c3660110b60297a4", 16)), + (CBigInt(new BigInteger("272c9672daa25c7bd48fcbf64f517961b300889b014bd200000000", 16)), + (CBigInt(new BigInteger("0", 16)), CBigInt(new BigInteger("80000000", 16)))))) )), + + ((CBigInt(new BigInteger("3d31398dc4783303", 16)), + CBigInt(new BigInteger("-37b381db4e6e927e202a2a421d5a09ca", 16))), + Failure(new ArithmeticException("BigInteger: modulus not positive"))), + + ((CBigInt(new BigInteger("5524814a26357cb71488b6fb26af2d3", 16)), + CBigInt(new BigInteger("c413b7d975a9972427f46996299fe57cfe79479ac954a7", 16))), + Failure(new ArithmeticException("BigInteger out of 256 bit range"))) + ) + }, existingFeature( { (x: (BigInt, BigInt)) => val a = x._1; val b = x._2 @@ -1256,7 +1338,7 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ) ) - ), true) + )) } property("BigInt methods equivalence (new features)") { @@ -1318,16 +1400,19 @@ class SigmaDslSpec extends SigmaDslTesting { suite => val ge2 = "02dba7b94b111f3894e2f9120b577da595ec7d58d488485adf73bf4e153af63575" val ge3 = "0290449814f5671172dd696a61b8aa49aaa4c87013f56165e27d49944e98bc414d" - testCases( - Seq( - (Helpers.decodeGroupElement(ge1), Success(Helpers.decodeBytes(ge1))), - (Helpers.decodeGroupElement(ge2), Success(Helpers.decodeBytes(ge2))), - (Helpers.decodeGroupElement(ge3), Success(Helpers.decodeBytes(ge3))), - (SigmaDsl.groupGenerator, - Success(Helpers.decodeBytes("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), - (SigmaDsl.groupIdentity, - Success(Helpers.decodeBytes("000000000000000000000000000000000000000000000000000000000000000000"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 37905)) + Seq( + (Helpers.decodeGroupElement(ge1), success(Helpers.decodeBytes(ge1))), + (Helpers.decodeGroupElement(ge2), success(Helpers.decodeBytes(ge2))), + (Helpers.decodeGroupElement(ge3), success(Helpers.decodeBytes(ge3))), + (SigmaDsl.groupGenerator, + success(Helpers.decodeBytes("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), + (SigmaDsl.groupIdentity, + success(Helpers.decodeBytes("000000000000000000000000000000000000000000000000000000000000000000"))) + ) + }, existingFeature((x: GroupElement) => x.getEncoded, "{ (x: GroupElement) => x.getEncoded }", FuncValue( @@ -1335,14 +1420,17 @@ class SigmaDslSpec extends SigmaDslTesting { suite => MethodCall(ValUse(1, SGroupElement), SGroupElement.getMethodByName("getEncoded"), Vector(), Map()) ))) - testCases( - Seq( - (Helpers.decodeGroupElement(ge1), Success(true)), - (Helpers.decodeGroupElement(ge2), Success(true)), - (Helpers.decodeGroupElement(ge3), Success(true)), - (SigmaDsl.groupGenerator, Success(true)), - (SigmaDsl.groupIdentity, Success(true)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 38340)) + Seq( + (Helpers.decodeGroupElement(ge1), success(true)), + (Helpers.decodeGroupElement(ge2), success(true)), + (Helpers.decodeGroupElement(ge3), success(true)), + (SigmaDsl.groupGenerator, success(true)), + (SigmaDsl.groupIdentity, success(true)) + ) + }, existingFeature({ (x: GroupElement) => decodePoint(x.getEncoded) == x }, "{ (x: GroupElement) => decodePoint(x.getEncoded) == x }", FuncValue( @@ -1360,14 +1448,17 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( - Seq( - (Helpers.decodeGroupElement(ge1), Success(Helpers.decodeGroupElement("02358d53f01276211f92d0aefbd278805121d4ff6eb534b777af1ee8abae5b2056"))), - (Helpers.decodeGroupElement(ge2), Success(Helpers.decodeGroupElement("03dba7b94b111f3894e2f9120b577da595ec7d58d488485adf73bf4e153af63575"))), - (Helpers.decodeGroupElement(ge3), Success(Helpers.decodeGroupElement("0390449814f5671172dd696a61b8aa49aaa4c87013f56165e27d49944e98bc414d"))), - (SigmaDsl.groupGenerator, Success(Helpers.decodeGroupElement("0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), - (SigmaDsl.groupIdentity, Success(Helpers.decodeGroupElement("000000000000000000000000000000000000000000000000000000000000000000"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36292)) + Seq( + (Helpers.decodeGroupElement(ge1), success(Helpers.decodeGroupElement("02358d53f01276211f92d0aefbd278805121d4ff6eb534b777af1ee8abae5b2056"))), + (Helpers.decodeGroupElement(ge2), success(Helpers.decodeGroupElement("03dba7b94b111f3894e2f9120b577da595ec7d58d488485adf73bf4e153af63575"))), + (Helpers.decodeGroupElement(ge3), success(Helpers.decodeGroupElement("0390449814f5671172dd696a61b8aa49aaa4c87013f56165e27d49944e98bc414d"))), + (SigmaDsl.groupGenerator, success(Helpers.decodeGroupElement("0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), + (SigmaDsl.groupIdentity, success(Helpers.decodeGroupElement("000000000000000000000000000000000000000000000000000000000000000000"))) + ) + }, existingFeature({ (x: GroupElement) => x.negate }, "{ (x: GroupElement) => x.negate }", FuncValue( @@ -1379,17 +1470,20 @@ class SigmaDslSpec extends SigmaDslTesting { suite => // val isIdentity = existingFeature({ (x: GroupElement) => x.isIdentity }, // "{ (x: GroupElement) => x.isIdentity }") - testCases( - Seq( - ((Helpers.decodeGroupElement(ge1), CBigInt(new BigInteger("-25c80b560dd7844e2efd10f80f7ee57d", 16))), - Success(Helpers.decodeGroupElement("023a850181b7b73f92a5bbfa0bfc78f5bbb6ff00645ddde501037017e1a2251e2e"))), - ((Helpers.decodeGroupElement(ge2), CBigInt(new BigInteger("2488741265082fb02b09f992be3dd8d60d2bbe80d9e2630", 16))), - Success(Helpers.decodeGroupElement("032045b928fb7774a4cd9ef5fa8209f4e493cd4cc5bd536b52746a53871bf73431"))), - ((Helpers.decodeGroupElement(ge3), CBigInt(new BigInteger("-33e8fbdb13d2982e92583445e1fdcb5901a178a7aa1e100", 16))), - Success(Helpers.decodeGroupElement("036128efaf14d8ac2812a662f6494dc617b87986a3dc6b4a59440048a7ac7d2729"))), - ((Helpers.decodeGroupElement(ge3), CBigInt(new BigInteger("1", 16))), - Success(Helpers.decodeGroupElement(ge3))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 41484)) + Seq( + ((Helpers.decodeGroupElement(ge1), CBigInt(new BigInteger("-25c80b560dd7844e2efd10f80f7ee57d", 16))), + success(Helpers.decodeGroupElement("023a850181b7b73f92a5bbfa0bfc78f5bbb6ff00645ddde501037017e1a2251e2e"))), + ((Helpers.decodeGroupElement(ge2), CBigInt(new BigInteger("2488741265082fb02b09f992be3dd8d60d2bbe80d9e2630", 16))), + success(Helpers.decodeGroupElement("032045b928fb7774a4cd9ef5fa8209f4e493cd4cc5bd536b52746a53871bf73431"))), + ((Helpers.decodeGroupElement(ge3), CBigInt(new BigInteger("-33e8fbdb13d2982e92583445e1fdcb5901a178a7aa1e100", 16))), + success(Helpers.decodeGroupElement("036128efaf14d8ac2812a662f6494dc617b87986a3dc6b4a59440048a7ac7d2729"))), + ((Helpers.decodeGroupElement(ge3), CBigInt(new BigInteger("1", 16))), + success(Helpers.decodeGroupElement(ge3))) + ) + }, existingFeature({ (x: (GroupElement, BigInt)) => x._1.exp(x._2) }, "{ (x: (GroupElement, BigInt)) => x._1.exp(x._2) }", FuncValue( @@ -1406,17 +1500,20 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( - Seq( - ((Helpers.decodeGroupElement(ge1), Helpers.decodeGroupElement("03e132ca090614bd6c9f811e91f6daae61f16968a1e6c694ed65aacd1b1092320e")), - Success(Helpers.decodeGroupElement("02bc48937b4a66f249a32dfb4d2efd0743dc88d46d770b8c5d39fd03325ba211df"))), - ((Helpers.decodeGroupElement(ge2), Helpers.decodeGroupElement("03e132ca090614bd6c9f811e91f6daae61f16968a1e6c694ed65aacd1b1092320e")), - Success(Helpers.decodeGroupElement("0359c3bb2ac4ea4dbd7b1e09d7b11198141a3263834fb84a88039629ec1e9311d1"))), - ((Helpers.decodeGroupElement(ge3), Helpers.decodeGroupElement("03e132ca090614bd6c9f811e91f6daae61f16968a1e6c694ed65aacd1b1092320e")), - Success(Helpers.decodeGroupElement("02eca42e28548d3fb9fa77cdd0c983066c3ad141ebb086b5044ce46b9ba9b5a714"))), - ((Helpers.decodeGroupElement(ge3), SigmaDsl.groupIdentity), - Success(Helpers.decodeGroupElement(ge3))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36457)) + Seq( + ((Helpers.decodeGroupElement(ge1), Helpers.decodeGroupElement("03e132ca090614bd6c9f811e91f6daae61f16968a1e6c694ed65aacd1b1092320e")), + success(Helpers.decodeGroupElement("02bc48937b4a66f249a32dfb4d2efd0743dc88d46d770b8c5d39fd03325ba211df"))), + ((Helpers.decodeGroupElement(ge2), Helpers.decodeGroupElement("03e132ca090614bd6c9f811e91f6daae61f16968a1e6c694ed65aacd1b1092320e")), + success(Helpers.decodeGroupElement("0359c3bb2ac4ea4dbd7b1e09d7b11198141a3263834fb84a88039629ec1e9311d1"))), + ((Helpers.decodeGroupElement(ge3), Helpers.decodeGroupElement("03e132ca090614bd6c9f811e91f6daae61f16968a1e6c694ed65aacd1b1092320e")), + success(Helpers.decodeGroupElement("02eca42e28548d3fb9fa77cdd0c983066c3ad141ebb086b5044ce46b9ba9b5a714"))), + ((Helpers.decodeGroupElement(ge3), SigmaDsl.groupIdentity), + success(Helpers.decodeGroupElement(ge3))) + ) + }, existingFeature({ (x: (GroupElement, GroupElement)) => x._1.multiply(x._2) }, "{ (x: (GroupElement, GroupElement)) => x._1.multiply(x._2) }", FuncValue( @@ -1471,72 +1568,93 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ) - testCases( - Seq( - (t1, Success(Helpers.decodeBytes("000183807f66b301530120ff7fc6bd6601ff01ff7f7d2bedbbffff00187fe89094"))), - (t2, Success(Helpers.decodeBytes("ff000d937f80ffd731ed802d24358001ff8080ff71007f00ad37e0a7ae43fff95b"))), - (t3, Success(Helpers.decodeBytes("3100d2e101ff01fc047c7f6f00ff80129df69a5090012f01ffca99f5bfff0c8036"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36182)) + Seq( + (t1, success(Helpers.decodeBytes("000183807f66b301530120ff7fc6bd6601ff01ff7f7d2bedbbffff00187fe89094"))), + (t2, success(Helpers.decodeBytes("ff000d937f80ffd731ed802d24358001ff8080ff71007f00ad37e0a7ae43fff95b"))), + (t3, success(Helpers.decodeBytes("3100d2e101ff01fc047c7f6f00ff80129df69a5090012f01ffca99f5bfff0c8036"))) + ) + }, existingFeature((t: AvlTree) => t.digest, "{ (t: AvlTree) => t.digest }", expectedExprFor("digest"))) - testCases( - Seq( - (t1, Success(6.toByte)), - (t2, Success(0.toByte)), - (t3, Success(1.toByte)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36260)) + Seq( + (t1, success(6.toByte)), + (t2, success(0.toByte)), + (t3, success(1.toByte)) + ) + }, existingFeature((t: AvlTree) => t.enabledOperations, "{ (t: AvlTree) => t.enabledOperations }", expectedExprFor("enabledOperations"))) - testCases( - Seq( - (t1, Success(1)), - (t2, Success(32)), - (t3, Success(128)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36136)) + Seq( + (t1, success(1)), + (t2, success(32)), + (t3, success(128)) + ) + }, existingFeature((t: AvlTree) => t.keyLength, "{ (t: AvlTree) => t.keyLength }", expectedExprFor("keyLength"))) - testCases( - Seq( - (t1, Success(Some(1))), - (t2, Success(Some(64))), - (t3, Success(None)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 37151)) + Seq( + (t1, success(Some(1))), + (t2, success(Some(64))), + (t3, success(None)) + ) + }, existingFeature((t: AvlTree) => t.valueLengthOpt, "{ (t: AvlTree) => t.valueLengthOpt }", expectedExprFor("valueLengthOpt"))) - testCases( - Seq( - (t1, Success(false)), - (t2, Success(false)), - (t3, Success(true)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36479)) + Seq( + (t1, success(false)), + (t2, success(false)), + (t3, success(true)) + ) + }, existingFeature((t: AvlTree) => t.isInsertAllowed, "{ (t: AvlTree) => t.isInsertAllowed }", expectedExprFor("isInsertAllowed"))) - testCases( - Seq( - (t1, Success(true)), - (t2, Success(false)), - (t3, Success(false)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36096)) + Seq( + (t1, success(true)), + (t2, success(false)), + (t3, success(false)) + ) + }, existingFeature((t: AvlTree) => t.isUpdateAllowed, "{ (t: AvlTree) => t.isUpdateAllowed }", expectedExprFor("isUpdateAllowed"))) - testCases( - Seq( - (t1, Success(true)), - (t2, Success(false)), - (t3, Success(false)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36502)) + Seq( + (t1, success(true)), + (t2, success(false)), + (t3, success(false)) + ) + }, existingFeature((t: AvlTree) => t.isRemoveAllowed, "{ (t: AvlTree) => t.isRemoveAllowed }", expectedExprFor("isRemoveAllowed"))) @@ -1741,24 +1859,56 @@ class SigmaDslSpec extends SigmaDslTesting { suite => val tree = SigmaDsl.avlTree(AvlTreeFlags.ReadOnly.serializeToByte, digest, 32, None) // positive test - contains.checkExpected((tree, (key, proof)), okContains) - get.checkExpected((tree, (key, proof)), valueOpt) + { + val input = (tree, (key, proof)) + contains.checkExpected(input, okContains) + get.checkExpected(input, valueOpt) + contains.checkVerify(input, expectedRes = okContains, expectedCost = 37850) + get.checkVerify(input, expectedRes = valueOpt, expectedCost = 38372) + } val keys = Colls.fromItems(key) val expRes = Colls.fromItems(valueOpt) - getMany.checkExpected((tree, (keys, proof)), expRes) + + { + val input = (tree, (keys, proof)) + getMany.checkExpected(input, expRes) + getMany.checkVerify(input, expectedRes = expRes, expectedCost = 38991) + } + + { + val input = (tree, digest) + val (res, _) = updateDigest.checkEquality(input).getOrThrow + res.digest shouldBe digest + updateDigest.checkVerify(input, expectedRes = res, expectedCost = 36341) + } - updateDigest.checkEquality((tree, digest)).get.digest shouldBe digest val newOps = 1.toByte - updateOperations.checkEquality((tree, newOps)).get.enabledOperations shouldBe newOps - { // negative tests: invalid proof - val invalidProof = proof.map(x => (-x).toByte) // any other different from proof - val resContains = contains.checkEquality((tree, (key, invalidProof))) - resContains shouldBe Success(false) + { + val input = (tree, newOps) + val (res,_) = updateOperations.checkEquality(input).getOrThrow + res.enabledOperations shouldBe newOps + updateOperations.checkVerify(input, expectedRes = res, expectedCost = 36341) + } + + // negative tests: invalid proof + val invalidProof = proof.map(x => (-x).toByte) // any other different from proof + + { + val input = (tree, (key, invalidProof)) + val (res, _) = contains.checkEquality(input).getOrThrow + res shouldBe false + contains.checkVerify(input, expectedRes = res, expectedCost = 37850) + } + + { val resGet = get.checkEquality((tree, (key, invalidProof))) resGet.isFailure shouldBe true + } + + { val resGetMany = getMany.checkEquality((tree, (keys, invalidProof))) resGetMany.isFailure shouldBe true } @@ -1870,22 +2020,28 @@ class SigmaDslSpec extends SigmaDslTesting { suite => { // positive val preInsertTree = createTree(preInsertDigest, insertAllowed = true) - val res = insert.checkEquality((preInsertTree, (kvs, insertProof))) - res.get.isDefined shouldBe true + val input = (preInsertTree, (kvs, insertProof)) + val (res, _) = insert.checkEquality(input).getOrThrow + res.isDefined shouldBe true + insert.checkVerify(input, expectedRes = res, expectedCost = 38501) } { // negative: readonly tree val readonlyTree = createTree(preInsertDigest) - val res = insert.checkEquality((readonlyTree, (kvs, insertProof))) - res.get.isDefined shouldBe false + val input = (readonlyTree, (kvs, insertProof)) + val (res, _) = insert.checkEquality(input).getOrThrow + res.isDefined shouldBe false + insert.checkVerify(input, expectedRes = res, expectedCost = 38501) } { // negative: invalid key val tree = createTree(preInsertDigest, insertAllowed = true) val invalidKey = key.map(x => (-x).toByte) // any other different from key val invalidKvs = Colls.fromItems((invalidKey -> value)) // NOTE, insertProof is based on `key` - val res = insert.checkEquality((tree, (invalidKvs, insertProof))) - res.get.isDefined shouldBe true // TODO HF: should it really be true? (looks like a bug) + val input = (tree, (invalidKvs, insertProof)) + val (res, _) = insert.checkEquality(input).getOrThrow + res.isDefined shouldBe true // TODO HF: should it really be true? (looks like a bug) + insert.checkVerify(input, expectedRes = res, expectedCost = 38501) } { // negative: invalid proof @@ -1965,6 +2121,7 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ) )) + val cost = 40952 forAll(keyCollGen, bytesCollGen) { (key, value) => val (_, avlProver) = createAvlTreeAndProver(key -> value) @@ -1977,39 +2134,53 @@ class SigmaDslSpec extends SigmaDslTesting { suite => { // positive: update to newValue val preUpdateTree = createTree(preUpdateDigest, updateAllowed = true) val endTree = preUpdateTree.updateDigest(endDigest) - update.checkExpected((preUpdateTree, (kvs, updateProof)), Some(endTree)) + val input = (preUpdateTree, (kvs, updateProof)) + val res = Some(endTree) + update.checkExpected(input, res) + update.checkVerify(input, expectedRes = res, expectedCost = cost) } { // positive: update to the same value (identity operation) val tree = createTree(preUpdateDigest, updateAllowed = true) val keys = Colls.fromItems((key -> value)) - update.checkExpected((tree, (keys, updateProof)), Some(tree)) + val input = (tree, (keys, updateProof)) + val res = Some(tree) + update.checkExpected(input, res) + update.checkVerify(input, expectedRes = res, expectedCost = cost) } { // negative: readonly tree val readonlyTree = createTree(preUpdateDigest) - val res = update.checkExpected((readonlyTree, (kvs, updateProof)), None) + val input = (readonlyTree, (kvs, updateProof)) + update.checkExpected(input, None) + update.checkVerify(input, expectedRes = None, expectedCost = 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)) - update.checkExpected((tree, (invalidKvs, updateProof)), None) + val input = (tree, (invalidKvs, updateProof)) + update.checkExpected(input, None) + update.checkVerify(input, expectedRes = None, expectedCost = 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 res = update.checkEquality((tree, (invalidKvs, updateProof))) - res.get.isDefined shouldBe true // TODO HF: should it really be true? (looks like a bug) + val input = (tree, (invalidKvs, updateProof)) + val (res, _) = update.checkEquality(input).getOrThrow + res.isDefined shouldBe true // TODO HF: should it really be true? (looks like a bug) + update.checkVerify(input, expectedRes = res, expectedCost = cost) } { // negative: invalid proof val tree = createTree(preUpdateDigest, updateAllowed = true) val invalidProof = updateProof.map(x => (-x).toByte) // any other different from proof - update.checkExpected((tree, (kvs, invalidProof)), None) + val input = (tree, (kvs, invalidProof)) + update.checkExpected(input, None) + update.checkVerify(input, expectedRes = None, expectedCost = cost) } } } @@ -2057,86 +2228,105 @@ class SigmaDslSpec extends SigmaDslTesting { suite => val removeProof = performRemove(avlProver, key) val endDigest = avlProver.digest.toColl val keys = Colls.fromItems(key) + val cost = 38270 { // positive val preRemoveTree = createTree(preRemoveDigest, removeAllowed = true) val endTree = preRemoveTree.updateDigest(endDigest) - remove.checkExpected((preRemoveTree, (keys, removeProof)), Some(endTree)) + val input = (preRemoveTree, (keys, removeProof)) + val res = Some(endTree) + remove.checkExpected(input, res) + remove.checkVerify(input, expectedRes = res, expectedCost = cost) } { // negative: readonly tree val readonlyTree = createTree(preRemoveDigest) - remove.checkExpected((readonlyTree, (keys, removeProof)), None) + val input = (readonlyTree, (keys, removeProof)) + remove.checkExpected(input, None) + remove.checkVerify(input, expectedRes = None, expectedCost = cost) } { // negative: invalid key val tree = createTree(preRemoveDigest, removeAllowed = true) val invalidKey = key.map(x => (-x).toByte) // any other different from `key` val invalidKeys = Colls.fromItems(invalidKey) - remove.checkExpected((tree, (invalidKeys, removeProof)), None) + val input = (tree, (invalidKeys, removeProof)) + remove.checkExpected(input, None) + remove.checkVerify(input, expectedRes = None, expectedCost = cost) } { // negative: invalid proof val tree = createTree(preRemoveDigest, removeAllowed = true) val invalidProof = removeProof.map(x => (-x).toByte) // any other different from `removeProof` - remove.checkExpected((tree, (keys, invalidProof)), None) + val input = (tree, (keys, invalidProof)) + remove.checkExpected(input, None) + remove.checkVerify(input, expectedRes = None, expectedCost = cost) } } } property("longToByteArray equivalence") { - testCases( - Seq( - (-9223372036854775808L, Success(Helpers.decodeBytes("8000000000000000"))), - (-1148502660425090565L, Success(Helpers.decodeBytes("f00fb2ea55c579fb"))), - (-1L, Success(Helpers.decodeBytes("ffffffffffffffff"))), - (0L, Success(Helpers.decodeBytes("0000000000000000"))), - (1L, Success(Helpers.decodeBytes("0000000000000001"))), - (238790047448232028L, Success(Helpers.decodeBytes("03505a48720cf05c"))), - (9223372036854775807L, Success(Helpers.decodeBytes("7fffffffffffffff"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36007)) + Seq( + (-9223372036854775808L, success(Helpers.decodeBytes("8000000000000000"))), + (-1148502660425090565L, success(Helpers.decodeBytes("f00fb2ea55c579fb"))), + (-1L, success(Helpers.decodeBytes("ffffffffffffffff"))), + (0L, success(Helpers.decodeBytes("0000000000000000"))), + (1L, success(Helpers.decodeBytes("0000000000000001"))), + (238790047448232028L, success(Helpers.decodeBytes("03505a48720cf05c"))), + (9223372036854775807L, success(Helpers.decodeBytes("7fffffffffffffff"))) + ) + }, existingFeature((x: Long) => SigmaDsl.longToByteArray(x), "{ (x: Long) => longToByteArray(x) }", FuncValue(Vector((1, SLong)), LongToByteArray(ValUse(1, SLong))))) } property("byteArrayToBigInt equivalence") { - testCases( - Seq( - (Helpers.decodeBytes(""), - Failure(new NumberFormatException("Zero length BigInteger"))), - (Helpers.decodeBytes("00"), - Success(CBigInt(new BigInteger("0", 16)))), - (Helpers.decodeBytes("01"), - Success(CBigInt(new BigInteger("1", 16)))), - (Helpers.decodeBytes("ff"), - Success(CBigInt(new BigInteger("-1", 16)))), - (Helpers.decodeBytes("80d6c201"), - Success(CBigInt(new BigInteger("-7f293dff", 16)))), - (Helpers.decodeBytes("70d6c201"), - Success(CBigInt(new BigInteger("70d6c201", 16)))), - (Helpers.decodeBytes( - "80e0ff7f02807fff72807f0a00ff7fb7c57f75c11ba2802970fd250052807fc37f6480ffff007fff18eeba44" - ), Failure(new ArithmeticException("BigInteger out of 256 bit range"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36536)) + Seq( + (Helpers.decodeBytes(""), + Failure(new NumberFormatException("Zero length BigInteger"))), + (Helpers.decodeBytes("00"), + success(CBigInt(new BigInteger("0", 16)))), + (Helpers.decodeBytes("01"), + success(CBigInt(new BigInteger("1", 16)))), + (Helpers.decodeBytes("ff"), + success(CBigInt(new BigInteger("-1", 16)))), + (Helpers.decodeBytes("80d6c201"), + Success(Expected(CBigInt(new BigInteger("-7f293dff", 16)), 36539))), + (Helpers.decodeBytes("70d6c20170d6c201"), + Success(Expected(CBigInt(new BigInteger("70d6c20170d6c201", 16)), 36543))), + (Helpers.decodeBytes( + "80e0ff7f02807fff72807f0a00ff7fb7c57f75c11ba2802970fd250052807fc37f6480ffff007fff18eeba44" + ), Failure(new ArithmeticException("BigInteger out of 256 bit range"))) + ) + }, existingFeature((x: Coll[Byte]) => SigmaDsl.byteArrayToBigInt(x), "{ (x: Coll[Byte]) => byteArrayToBigInt(x) }", FuncValue(Vector((1, SByteArray)), ByteArrayToBigInt(ValUse(1, SByteArray))))) } property("byteArrayToLong equivalence") { - testCases( - Seq( - (Helpers.decodeBytes(""), Failure(new IllegalArgumentException("array too small: 0 < 8"))), - (Helpers.decodeBytes("81"), Failure(new IllegalArgumentException("array too small: 1 < 8"))), - (Helpers.decodeBytes("812d7f00ff807f"), Failure(new IllegalArgumentException("array too small: 7 < 8"))), - (Helpers.decodeBytes("812d7f00ff807f7f"), Success(-9138508426601529473L)), - (Helpers.decodeBytes("ffffffffffffffff"), Success(-1L)), - (Helpers.decodeBytes("0000000000000000"), Success(0L)), - (Helpers.decodeBytes("0000000000000001"), Success(1L)), - (Helpers.decodeBytes("712d7f00ff807f7f"), Success(8155314142501175167L)), - (Helpers.decodeBytes("812d7f00ff807f7f0101018050757f0580ac009680f2ffc1"), Success(-9138508426601529473L)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36092)) + Seq( + (Helpers.decodeBytes(""), Failure(new IllegalArgumentException("array too small: 0 < 8"))), + (Helpers.decodeBytes("81"), Failure(new IllegalArgumentException("array too small: 1 < 8"))), + (Helpers.decodeBytes("812d7f00ff807f"), Failure(new IllegalArgumentException("array too small: 7 < 8"))), + (Helpers.decodeBytes("812d7f00ff807f7f"), success(-9138508426601529473L)), + (Helpers.decodeBytes("ffffffffffffffff"), success(-1L)), + (Helpers.decodeBytes("0000000000000000"), success(0L)), + (Helpers.decodeBytes("0000000000000001"), success(1L)), + (Helpers.decodeBytes("712d7f00ff807f7f"), success(8155314142501175167L)), + (Helpers.decodeBytes("812d7f00ff807f7f0101018050757f0580ac009680f2ffc1"), success(-9138508426601529473L)) + ) + }, existingFeature((x: Coll[Byte]) => SigmaDsl.byteArrayToLong(x), "{ (x: Coll[Byte]) => byteArrayToLong(x) }", FuncValue(Vector((1, SByteArray)), ByteArrayToLong(ValUse(1, SByteArray))))) @@ -2229,86 +2419,103 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ) - testCases( - Seq( - (b1, Success(Helpers.decodeBytes("5ee78f30ae4e770e44900a46854e9fecb6b12e8112556ef1cd19aef633b4421e"))), - (b2, Success(Helpers.decodeBytes("3a0089be265460e29ca47d26e5b55a6f3e3ffaf5b4aed941410a2437913848ad"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35984)) + Seq( + (b1, success(Helpers.decodeBytes("5ee78f30ae4e770e44900a46854e9fecb6b12e8112556ef1cd19aef633b4421e"))), + (b2, success(Helpers.decodeBytes("3a0089be265460e29ca47d26e5b55a6f3e3ffaf5b4aed941410a2437913848ad"))) + ) + }, existingFeature({ (x: Box) => x.id }, "{ (x: Box) => x.id }", FuncValue(Vector((1, SBox)), ExtractId(ValUse(1, SBox))))) - testCases( - Seq( - (b1, Success(9223372036854775807L)), - (b2, Success(12345L)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35882)) + Seq( + (b1, success(9223372036854775807L)), + (b2, success(12345L)) + ) + }, existingFeature({ (x: Box) => x.value }, "{ (x: Box) => x.value }", FuncValue(Vector((1, SBox)), ExtractAmount(ValUse(1, SBox))))) - testCases( - Seq( - (b1, Success(Helpers.decodeBytes( - "100108cd0297c44a12f4eb99a85d298fa3ba829b5b42b9f63798c980ece801cc663cc5fc9e7300" - ))), - (b2, Success(Helpers.decodeBytes("00d1968302010100ff83020193040204020100"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35938)) + Seq( + (b1, success(Helpers.decodeBytes( + "100108cd0297c44a12f4eb99a85d298fa3ba829b5b42b9f63798c980ece801cc663cc5fc9e7300" + ))), + (b2, success(Helpers.decodeBytes("00d1968302010100ff83020193040204020100"))) + ) + }, existingFeature({ (x: Box) => x.propositionBytes }, "{ (x: Box) => x.propositionBytes }", FuncValue(Vector((1, SBox)), ExtractScriptBytes(ValUse(1, SBox))))) - testCases( - Seq( - (b1, Success(Helpers.decodeBytes( - "ffffffffffffffff7f100108cd0297c44a12f4eb99a85d298fa3ba829b5b42b9f63798c980ece801cc663cc5fc9e73009fac29026e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f000180ade204a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600f4030201000e067fc87f7f01ff218301ae8000018008637f0021fb9e00018055486f0b514121016a00ff718080bcb001" - ))), - (b2, Success(Helpers.decodeBytes( - "b96000d1968302010100ff83020193040204020100c0843d000401010e32297000800b80f1d56c809a8c6affbed864b87f007f6f007f00ac00018c01c4fdff011088807f0100657f00f9ab0101ff6d6505a4a7b5a2e7a4a4dd3a05feffffffffffffffff01003bd5c630803cfff6c1ff7f7fb980ff136afc011f8080b8b04ad4dbda2d7f4e01" - ))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36012)) + Seq( + (b1, success(Helpers.decodeBytes( + "ffffffffffffffff7f100108cd0297c44a12f4eb99a85d298fa3ba829b5b42b9f63798c980ece801cc663cc5fc9e73009fac29026e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f000180ade204a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600f4030201000e067fc87f7f01ff218301ae8000018008637f0021fb9e00018055486f0b514121016a00ff718080bcb001" + ))), + (b2, success(Helpers.decodeBytes( + "b96000d1968302010100ff83020193040204020100c0843d000401010e32297000800b80f1d56c809a8c6affbed864b87f007f6f007f00ac00018c01c4fdff011088807f0100657f00f9ab0101ff6d6505a4a7b5a2e7a4a4dd3a05feffffffffffffffff01003bd5c630803cfff6c1ff7f7fb980ff136afc011f8080b8b04ad4dbda2d7f4e01" + ))) + ) + }, existingFeature({ (x: Box) => x.bytes }, "{ (x: Box) => x.bytes }", FuncValue(Vector((1, SBox)), ExtractBytes(ValUse(1, SBox))))) - testCases( - Seq( - (b1, Success(Helpers.decodeBytes( - "ffffffffffffffff7f100108cd0297c44a12f4eb99a85d298fa3ba829b5b42b9f63798c980ece801cc663cc5fc9e73009fac29026e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f000180ade204a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600f4030201000e067fc87f7f01ff" - ))), - (b2, Success(Helpers.decodeBytes( - "b96000d1968302010100ff83020193040204020100c0843d000401010e32297000800b80f1d56c809a8c6affbed864b87f007f6f007f00ac00018c01c4fdff011088807f0100657f00f9ab0101ff6d6505a4a7b5a2e7a4a4dd3a05feffffffffffffffff01" - ))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35954)) + Seq( + (b1, success(Helpers.decodeBytes( + "ffffffffffffffff7f100108cd0297c44a12f4eb99a85d298fa3ba829b5b42b9f63798c980ece801cc663cc5fc9e73009fac29026e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f000180ade204a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600f4030201000e067fc87f7f01ff" + ))), + (b2, success(Helpers.decodeBytes( + "b96000d1968302010100ff83020193040204020100c0843d000401010e32297000800b80f1d56c809a8c6affbed864b87f007f6f007f00ac00018c01c4fdff011088807f0100657f00f9ab0101ff6d6505a4a7b5a2e7a4a4dd3a05feffffffffffffffff01" + ))) + ) + }, existingFeature({ (x: Box) => x.bytesWithoutRef }, "{ (x: Box) => x.bytesWithoutRef }", FuncValue(Vector((1, SBox)), ExtractBytesWithNoRef(ValUse(1, SBox))))) - testCases( - Seq( - (b1, Success(( - 677407, - Helpers.decodeBytes("218301ae8000018008637f0021fb9e00018055486f0b514121016a00ff718080583c") - ))), - (b2, Success(( - 1000000, - Helpers.decodeBytes("003bd5c630803cfff6c1ff7f7fb980ff136afc011f8080b8b04ad4dbda2d7f4e0001") - ))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36074)) + Seq( + (b1, success(( + 677407, + Helpers.decodeBytes("218301ae8000018008637f0021fb9e00018055486f0b514121016a00ff718080583c") + ))), + (b2, success(( + 1000000, + Helpers.decodeBytes("003bd5c630803cfff6c1ff7f7fb980ff136afc011f8080b8b04ad4dbda2d7f4e0001") + ))) + ) + }, existingFeature({ (x: Box) => x.creationInfo }, "{ (x: Box) => x.creationInfo }", FuncValue(Vector((1, SBox)), ExtractCreationInfo(ValUse(1, SBox))))) // TODO HF: fix collections equality and remove map(identity) // (PairOfColl should be equal CollOverArray) - testCases( + verifyCases( Seq( - (b1, Success(Coll[(Coll[Byte], Long)]( - (Helpers.decodeBytes("6e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f0001"), 10000000L), - (Helpers.decodeBytes("a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600"), 500L) - ).map(identity)) - ), - (b2, Success(Coll[(Coll[Byte], Long)]().map(identity))) + b1 -> Success(Expected(Coll[(Coll[Byte], Long)]( + (Helpers.decodeBytes("6e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f0001"), 10000000L), + (Helpers.decodeBytes("a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600"), 500L) + ).map(identity), 36167)), + b2 -> Success(Expected(Coll[(Coll[Byte], Long)]().map(identity), 36157)) ), existingFeature({ (x: Box) => x.tokens }, "{ (x: Box) => x.tokens }", @@ -2321,7 +2528,6 @@ class SigmaDslSpec extends SigmaDslTesting { suite => Map() ) ))) - } property("Box properties equivalence (new features)") { @@ -2337,7 +2543,7 @@ class SigmaDslSpec extends SigmaDslTesting { suite => property("Advanced Box test") { val (tree, _) = createAvlTreeAndProver() - val box1 = SigmaDsl.Box(ErgoBox(20, TrueProp, 0, Seq(), Map( + val box1 = SigmaDsl.Box(testBox(20, TrueProp, 0, Seq(), Map( ErgoBox.R4 -> ByteConstant(1.toByte), ErgoBox.R5 -> ShortConstant(1024.toShort), ErgoBox.R6 -> IntConstant(1024 * 1024), @@ -2346,13 +2552,13 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ErgoBox.R9 -> AvlTreeConstant(tree) ))) - val box2 = SigmaDsl.Box(ErgoBox(20, TrueProp, 0, Seq(), Map( + val box2 = SigmaDsl.Box(testBox(20, TrueProp, 0, Seq(), Map( ErgoBox.R4 -> ByteArrayConstant(Coll(1.toByte)) ))) - testCases( + verifyCases( Seq( - (box1, Success(1.toByte)), + (box1, Success(Expected(1.toByte, cost = 36253))), (box2, Failure(new InvalidType("Cannot getReg[Byte](4): invalid type of value Value(Coll(1)) at id=4"))) ), existingFeature((x: Box) => x.R4[Byte].get, @@ -2362,9 +2568,9 @@ class SigmaDslSpec extends SigmaDslTesting { suite => OptionGet(ExtractRegisterAs(ValUse(1, SBox), ErgoBox.R4, SOption(SByte))) ))) - testCases( + verifyCases( Seq( - (box1, Success(1024.toShort)), + (box1, Success(Expected(1024.toShort, cost = 36253))), (box2, Failure(new NoSuchElementException("None.get"))) ), existingFeature((x: Box) => x.R5[Short].get, @@ -2374,9 +2580,9 @@ class SigmaDslSpec extends SigmaDslTesting { suite => OptionGet(ExtractRegisterAs(ValUse(1, SBox), ErgoBox.R5, SOption(SShort))) ))) - testCases( + verifyCases( Seq( - (box1, Success(1024 * 1024)) + (box1, Success(Expected(1024 * 1024, cost = 36253))) ), existingFeature((x: Box) => x.R6[Int].get, "{ (x: Box) => x.R6[Int].get }", @@ -2385,9 +2591,9 @@ class SigmaDslSpec extends SigmaDslTesting { suite => OptionGet(ExtractRegisterAs(ValUse(1, SBox), ErgoBox.R6, SOption(SInt))) ))) - testCases( + verifyCases( Seq( - (box1, Success(1024.toLong)) + (box1, Success(Expected(1024.toLong, cost = 36253))) ), existingFeature((x: Box) => x.R7[Long].get, "{ (x: Box) => x.R7[Long].get }", @@ -2396,9 +2602,9 @@ class SigmaDslSpec extends SigmaDslTesting { suite => OptionGet(ExtractRegisterAs(ValUse(1, SBox), ErgoBox.R7, SOption(SLong))) ))) - testCases( + verifyCases( Seq( - (box1, Success(CBigInt(BigInteger.valueOf(222L)))) + (box1, Success(Expected(CBigInt(BigInteger.valueOf(222L)), cost = 36253))) ), existingFeature((x: Box) => x.R8[BigInt].get, "{ (x: Box) => x.R8[BigInt].get }", @@ -2407,9 +2613,9 @@ class SigmaDslSpec extends SigmaDslTesting { suite => OptionGet(ExtractRegisterAs(ValUse(1, SBox), ErgoBox.R8, SOption(SBigInt))) ))) - testCases( + verifyCases( Seq( - (box1, Success(CAvlTree( + (box1, Success(Expected(CAvlTree( AvlTreeData( ADDigest @@ ( ErgoAlgos.decodeUnsafe("4ec61f485b98eb87153f7c57db4f5ecd75556fddbc403b41acf8441fde8e160900") @@ -2418,7 +2624,7 @@ class SigmaDslSpec extends SigmaDslTesting { suite => 32, None ) - ))) + ), cost = 36253))) ), existingFeature((x: Box) => x.R9[AvlTree].get, "{ (x: Box) => x.R9[AvlTree].get }", @@ -2451,32 +2657,36 @@ class SigmaDslSpec extends SigmaDslTesting { suite => Helpers.decodeBytes("ff8087") ) - testCases( - Seq((h1, Success(0.toByte))), + verifyCases( + Seq((h1, Success(Expected(0.toByte, cost = 37022)))), existingPropTest("version", { (x: PreHeader) => x.version })) - testCases( - Seq((h1, Success(Helpers.decodeBytes("7fff7fdd6f62018bae0001006d9ca888ff7f56ff8006573700a167f17f2c9f40")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeBytes("7fff7fdd6f62018bae0001006d9ca888ff7f56ff8006573700a167f17f2c9f40"), + cost = 36121)))), existingPropTest("parentId", { (x: PreHeader) => x.parentId })) - testCases( - Seq((h1, Success(6306290372572472443L))), + verifyCases( + Seq((h1, Success(Expected(6306290372572472443L, cost = 36147)))), existingPropTest("timestamp", { (x: PreHeader) => x.timestamp })) - testCases( - Seq((h1, Success(-3683306095029417063L))), + verifyCases( + Seq((h1, Success(Expected(-3683306095029417063L, cost = 36127)))), existingPropTest("nBits", { (x: PreHeader) => x.nBits })) - testCases( - Seq((h1, Success(1))), + verifyCases( + Seq((h1, Success(Expected(1, cost = 36136)))), existingPropTest("height", { (x: PreHeader) => x.height })) - testCases( - Seq((h1, Success(Helpers.decodeGroupElement("026930cb9972e01534918a6f6d6b8e35bc398f57140d13eb3623ea31fbd069939b")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeGroupElement("026930cb9972e01534918a6f6d6b8e35bc398f57140d13eb3623ea31fbd069939b"), + cost = 36255)))), existingPropTest("minerPk", { (x: PreHeader) => x.minerPk })) - testCases( - Seq((h1, Success(Helpers.decodeBytes("ff8087")))), + verifyCases( + Seq((h1, Success(Expected(Helpers.decodeBytes("ff8087"), cost = 36249)))), existingPropTest("votes", { (x: PreHeader) => x.votes })) } @@ -2507,64 +2717,84 @@ class SigmaDslSpec extends SigmaDslTesting { suite => Helpers.decodeBytes("7f0180") ) - testCases( - Seq((h1, Success(Helpers.decodeBytes("957f008001808080ffe4ffffc8f3802401df40006aa05e017fa8d3f6004c804a")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeBytes("957f008001808080ffe4ffffc8f3802401df40006aa05e017fa8d3f6004c804a"), + cost = 36955)))), existingPropTest("id", { (x: Header) => x.id })) - testCases( - Seq((h1, Success(0.toByte))), + verifyCases( + Seq((h1, Success(Expected(0.toByte, cost = 36124)))), existingPropTest("version", { (x: Header) => x.version })) - testCases( - Seq((h1, Success(Helpers.decodeBytes("0180dd805b0000ff5400b997fd7f0b9b00de00fb03c47e37806a8186b94f07ff")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeBytes("0180dd805b0000ff5400b997fd7f0b9b00de00fb03c47e37806a8186b94f07ff"), + cost = 36097)))), existingPropTest("parentId", { (x: Header) => x.parentId })) - testCases( - Seq((h1, Success(Helpers.decodeBytes("01f07f60d100ffb970c3007f60ff7f24d4070bb8fffa7fca7f34c10001ffe39d")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeBytes("01f07f60d100ffb970c3007f60ff7f24d4070bb8fffa7fca7f34c10001ffe39d"), + cost = 36111)))), existingPropTest("ADProofsRoot", { (x: Header) => x.ADProofsRoot})) - testCases( - Seq((h1, Success(CAvlTree(treeData)))), + verifyCases( + Seq((h1, Success(Expected(CAvlTree(treeData), cost = 36092)))), existingPropTest("stateRoot", { (x: Header) => x.stateRoot })) - testCases( - Seq((h1, Success(Helpers.decodeBytes("804101ff01000080a3ffbd006ac080098df132a7017f00649311ec0e00000100")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeBytes("804101ff01000080a3ffbd006ac080098df132a7017f00649311ec0e00000100"), + cost = 36094)))), existingPropTest("transactionsRoot", { (x: Header) => x.transactionsRoot })) - testCases( - Seq((h1, Success(1L))), + verifyCases( + Seq((h1, Success(Expected(1L, cost = 36151)))), existingPropTest("timestamp", { (x: Header) => x.timestamp })) - testCases( - Seq((h1, Success(-1L))), + verifyCases( + Seq((h1, Success(Expected(-1L, cost = 36125)))), existingPropTest("nBits", { (x: Header) => x.nBits })) - testCases( - Seq((h1, Success(1))), + verifyCases( + Seq((h1, Success(Expected(1, cost = 36134)))), existingPropTest("height", { (x: Header) => x.height })) - testCases( - Seq((h1, Success(Helpers.decodeBytes("e57f80885601b8ff348e01808000bcfc767f2dd37f0d01015030ec018080bc62")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeBytes("e57f80885601b8ff348e01808000bcfc767f2dd37f0d01015030ec018080bc62"), + cost = 36133)))), existingPropTest("extensionRoot", { (x: Header) => x.extensionRoot })) - testCases( - Seq((h1, Success(Helpers.decodeGroupElement("039bdbfa0b49cc6bef58297a85feff45f7bbeb500a9d2283004c74fcedd4bd2904")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeGroupElement("039bdbfa0b49cc6bef58297a85feff45f7bbeb500a9d2283004c74fcedd4bd2904"), + cost = 36111)))), existingPropTest("minerPk", { (x: Header) => x.minerPk })) - testCases( - Seq((h1, Success(Helpers.decodeGroupElement("0361299207fa392231e23666f6945ae3e867b978e021d8d702872bde454e9abe9c")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeGroupElement("0361299207fa392231e23666f6945ae3e867b978e021d8d702872bde454e9abe9c"), + cost = 36111)))), existingPropTest("powOnetimePk", { (x: Header) => x.powOnetimePk })) - testCases( - Seq((h1, Success(Helpers.decodeBytes("7f4f09012a807f01")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeBytes("7f4f09012a807f01"), + cost = 36176)))), existingPropTest("powNonce", { (x: Header) => x.powNonce })) - testCases( - Seq((h1, Success(CBigInt(new BigInteger("-e24990c47e15ed4d0178c44f1790cc72155d516c43c3e8684e75db3800a288", 16))))), + verifyCases( + Seq((h1, Success(Expected( + CBigInt(new BigInteger("-e24990c47e15ed4d0178c44f1790cc72155d516c43c3e8684e75db3800a288", 16)), + cost = 36220)))), existingPropTest("powDistance", { (x: Header) => x.powDistance })) - testCases( - Seq((h1, Success(Helpers.decodeBytes("7f0180")))), + verifyCases( + Seq((h1, Success(Expected( + Helpers.decodeBytes("7f0180"), + cost = 36100)))), existingPropTest("votes", { (x: Header) => x.votes })) } @@ -2735,7 +2965,11 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ), _minerPubKey = Helpers.decodeBytes("0227a58e9b2537103338c237c52c1213bf44bdb344fa07d9df8ab826cca26ca08f"), - vars = Coll[AnyValue](null, TestValue(Helpers.decodeBytes("00"), CollType(RType.ByteType)), TestValue(true, RType.BooleanType)), + vars = Colls + .replicate[AnyValue](10, null) // reserve 10 vars + .append(Coll[AnyValue]( + TestValue(Helpers.decodeBytes("00"), CollType(RType.ByteType)), + TestValue(true, RType.BooleanType))), false ) val ctx2 = ctx.copy(vars = Coll[AnyValue](null, null, null)) @@ -2743,69 +2977,91 @@ class SigmaDslSpec extends SigmaDslTesting { suite => test(samples, existingPropTest("dataInputs", { (x: Context) => x.dataInputs })) - testCases( + verifyCases( Seq( - (ctx, Success(dataBox)), + (ctx, Success(Expected(dataBox, cost = 37087))), (ctx.copy(_dataInputs = Coll()), Failure(new ArrayIndexOutOfBoundsException("0"))) ), existingFeature({ (x: Context) => x.dataInputs(0) }, "{ (x: Context) => x.dataInputs(0) }", FuncValue( - Vector((1, SContext)), - ByIndex( - MethodCall.typed[Value[SCollection[SBox.type]]]( - ValUse(1, SContext), - SContext.getMethodByName("dataInputs"), - Vector(), - Map() - ), - IntConstant(0), - None - ) - )), + Vector((1, SContext)), + ByIndex( + MethodCall.typed[Value[SCollection[SBox.type]]]( + ValUse(1, SContext), + SContext.getMethodByName("dataInputs"), + Vector(), + Map() + ), + IntConstant(0), + None + ) + )), preGeneratedSamples = Some(samples)) - testCases( + verifyCases( Seq( - (ctx, Success(Helpers.decodeBytes("7da4b55971f19a78d007638464580f91a020ab468c0dbe608deb1f619e245bc3"))) + (ctx, Success(Expected( + Helpers.decodeBytes("7da4b55971f19a78d007638464580f91a020ab468c0dbe608deb1f619e245bc3"), + cost = 37193))) ), existingFeature({ (x: Context) => x.dataInputs(0).id }, "{ (x: Context) => x.dataInputs(0).id }", FuncValue( - Vector((1, SContext)), - ExtractId( - ByIndex( - MethodCall.typed[Value[SCollection[SBox.type]]]( - ValUse(1, SContext), - SContext.getMethodByName("dataInputs"), - Vector(), - Map() - ), - IntConstant(0), - None - ) - ) - )), + Vector((1, SContext)), + ExtractId( + ByIndex( + MethodCall.typed[Value[SCollection[SBox.type]]]( + ValUse(1, SContext), + SContext.getMethodByName("dataInputs"), + Vector(), + Map() + ), + IntConstant(0), + None + ) + ) + )), preGeneratedSamples = Some(samples)) - test(samples, existingPropTest("preHeader", { (x: Context) => x.preHeader })) + // NOTE: testCases2 is not used below because PreHeader/Header cannot be put in + // registers and context vars + testCases( + Seq(ctx -> Success(ctx.preHeader)), + existingPropTest("preHeader", { (x: Context) => x.preHeader }), + preGeneratedSamples = Some(samples)) - test(samples, existingPropTest("headers", { (x: Context) => x.headers })) + testCases( + Seq(ctx -> Success(ctx.headers)), + existingPropTest("headers", { (x: Context) => x.headers }), + preGeneratedSamples = Some(samples)) - test(samples, existingFeature({ (x: Context) => x.OUTPUTS }, - "{ (x: Context) => x.OUTPUTS }", FuncValue(Vector((1, SContext)), Outputs))) + // TODO: testCases2 doesn't work because of equality (check the reason) + testCases( + Seq(ctx -> Success(ctx.OUTPUTS)), + existingFeature( + { (x: Context) => x.OUTPUTS }, + "{ (x: Context) => x.OUTPUTS }", + FuncValue(Vector((1, SContext)), Outputs)), + preGeneratedSamples = Some(samples)) + // NOTE: testCases2 is not supported because SELF modified to pass input test(samples, existingFeature({ (x: Context) => x.INPUTS }, "{ (x: Context) => x.INPUTS }", FuncValue(Vector((1, SContext)), Inputs))) - test(samples, existingFeature({ (x: Context) => x.HEIGHT }, - "{ (x: Context) => x.HEIGHT }", FuncValue(Vector((1, SContext)), Height))) - test(samples, existingFeature({ (x: Context) => x.SELF }, - "{ (x: Context) => x.SELF }", FuncValue(Vector((1, SContext)), Self))) + "{ (x: Context) => x.SELF }", FuncValue(Vector((1, SContext)), Self))) - testCases( - Seq((ctx, Success(Coll[Long](80946L)))), + verifyCases( + Seq(ctx -> Success(Expected(ctx.HEIGHT, cost = 35885))), + existingFeature( + { (x: Context) => x.HEIGHT }, + "{ (x: Context) => x.HEIGHT }", + FuncValue(Vector((1, SContext)), Height)), + preGeneratedSamples = Some(samples)) + + verifyCases( + Seq((ctx, Success(Expected(Coll[Long](80946L), cost = 39152)))), existingFeature( { (x: Context) => x.INPUTS.map { (b: Box) => b.value } }, "{ (x: Context) => x.INPUTS.map { (b: Box) => b.value } }", @@ -2815,30 +3071,29 @@ class SigmaDslSpec extends SigmaDslTesting { suite => )), preGeneratedSamples = Some(samples)) - testCases( - Seq((ctx, Success(Coll((80946L, 80946L))))), + verifyCases( + Seq((ctx, Success(Expected(Coll((80946L, 80946L)), cost = 39959)))), existingFeature( { (x: Context) => x.INPUTS.map { (b: Box) => (b.value, b.value) } }, """{ (x: Context) => | x.INPUTS.map { (b: Box) => (b.value, b.value) } |}""".stripMargin, FuncValue( - Vector((1, SContext)), - MapCollection( - Inputs, - FuncValue( - Vector((3, SBox)), - BlockValue( - Vector(ValDef(5, List(), ExtractAmount(ValUse(3, SBox)))), - Tuple(Vector(ValUse(5, SLong), ValUse(5, SLong))) - ) - ) - ) - )), + Vector((1, SContext)), + MapCollection( + Inputs, + FuncValue( + Vector((3, SBox)), + BlockValue( + Vector(ValDef(5, List(), ExtractAmount(ValUse(3, SBox)))), + Tuple(Vector(ValUse(5, SLong), ValUse(5, SLong))) + ) + ) + ) + )), preGeneratedSamples = Some(samples)) - - testCases( + verifyCases( Seq((ctx, Failure(new InvalidType("Cannot getReg[Int](4): invalid type of value Value(Coll(52)) at id=4")))), existingFeature( { (x: Context) => @@ -2856,35 +3111,35 @@ class SigmaDslSpec extends SigmaDslTesting { suite => | } |}""".stripMargin, FuncValue( - Vector((1, SContext)), - MapCollection( - Inputs, - FuncValue( - Vector((3, SBox)), - Tuple( - Vector( - OptionGet(ExtractRegisterAs(ValUse(3, SBox), ErgoBox.R4, SOption(SInt))), - LongToByteArray(ExtractAmount(ValUse(3, SBox))) - ) - ) - ) - ) - )), + Vector((1, SContext)), + MapCollection( + Inputs, + FuncValue( + Vector((3, SBox)), + Tuple( + Vector( + OptionGet(ExtractRegisterAs(ValUse(3, SBox), ErgoBox.R4, SOption(SInt))), + LongToByteArray(ExtractAmount(ValUse(3, SBox))) + ) + ) + ) + ) + )), preGeneratedSamples = Some(samples)) - testCases( - Seq((ctx, Success(-1))), + verifyCases( + Seq((ctx, Success(Expected(-1, cost = 36318)))), existingFeature({ (x: Context) => x.selfBoxIndex }, "{ (x: Context) => x.selfBoxIndex }", FuncValue( - Vector((1, SContext)), - MethodCall.typed[Value[SInt.type]]( - ValUse(1, SContext), - SContext.getMethodByName("selfBoxIndex"), - Vector(), - Map() - ) - )), + Vector((1, SContext)), + MethodCall.typed[Value[SInt.type]]( + ValUse(1, SContext), + SContext.getMethodByName("selfBoxIndex"), + Vector(), + Map() + ) + )), preGeneratedSamples = Some(samples)) // TODO HF: see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/603 @@ -2892,166 +3147,200 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ctx.selfBoxIndex shouldBe -1 } - test(samples, - existingPropTest("LastBlockUtxoRootHash", { (x: Context) => x.LastBlockUtxoRootHash })) + verifyCases( + Seq(ctx -> Success(Expected(ctx.LastBlockUtxoRootHash, cost = 35990))), + existingPropTest("LastBlockUtxoRootHash", { (x: Context) => x.LastBlockUtxoRootHash }), + preGeneratedSamples = Some(samples)) - test(samples, existingFeature( - { (x: Context) => x.LastBlockUtxoRootHash.isUpdateAllowed }, - "{ (x: Context) => x.LastBlockUtxoRootHash.isUpdateAllowed }", - FuncValue( - Vector((1, SContext)), - MethodCall.typed[Value[SBoolean.type]]( - MethodCall.typed[Value[SAvlTree.type]]( - ValUse(1, SContext), - SContext.getMethodByName("LastBlockUtxoRootHash"), + verifyCases( + Seq(ctx -> Success(Expected(ctx.LastBlockUtxoRootHash.isUpdateAllowed, cost = 36288))), + existingFeature( + { (x: Context) => x.LastBlockUtxoRootHash.isUpdateAllowed }, + "{ (x: Context) => x.LastBlockUtxoRootHash.isUpdateAllowed }", + FuncValue( + Vector((1, SContext)), + MethodCall.typed[Value[SBoolean.type]]( + MethodCall.typed[Value[SAvlTree.type]]( + ValUse(1, SContext), + SContext.getMethodByName("LastBlockUtxoRootHash"), + Vector(), + Map() + ), + SAvlTree.getMethodByName("isUpdateAllowed"), Vector(), Map() - ), - SAvlTree.getMethodByName("isUpdateAllowed"), - Vector(), - Map() - ) - ))) + ) + )), + preGeneratedSamples = Some(samples)) - test(samples, existingPropTest("minerPubKey", { (x: Context) => x.minerPubKey })) + verifyCases( + Seq(ctx -> Success(Expected(ctx.minerPubKey, cost = 36047))), + existingPropTest("minerPubKey", { (x: Context) => x.minerPubKey }), + preGeneratedSamples = Some(samples)) +// TODO HF: implement support of Option[T] in DataSerializer +// this will allow passing optional values in registers and also in constants +// testCases2( +// Seq( +// ctx -> Success(Expected(Some(true), cost = 0)), +// ctx2 -> Success(Expected(None, cost = 0)), +// ctx3 -> Success(Expected(None, cost = 0)) +// ), testCases( Seq( ctx -> Success(Some(true)), ctx2 -> Success(None), ctx3 -> Success(None) ), - existingFeature((x: Context) => x.getVar[Boolean](2), - "{ (x: Context) => getVar[Boolean](2) }", - FuncValue(Vector((1, SContext)), GetVar(2.toByte, SOption(SBoolean)))), + existingFeature((x: Context) => x.getVar[Boolean](11), + "{ (x: Context) => getVar[Boolean](11) }", + FuncValue(Vector((1, SContext)), GetVar(11.toByte, SOption(SBoolean)))), preGeneratedSamples = Some(samples)) - testCases( - Seq((ctx, Failure(new InvalidType("Cannot getVar[Int](2): invalid type of value Value(true) at id=2")))), - existingFeature((x: Context) => x.getVar[Int](2).get, - "{ (x: Context) => getVar[Int](2).get }", - FuncValue(Vector((1, SContext)), OptionGet(GetVar(2.toByte, SOption(SInt))))), + verifyCases( + Seq((ctx, Failure(new InvalidType("Cannot getVar[Int](11): invalid type of value Value(true) at id=2")))), + existingFeature((x: Context) => x.getVar[Int](11).get, + "{ (x: Context) => getVar[Int](11).get }", + FuncValue(Vector((1, SContext)), OptionGet(GetVar(11.toByte, SOption(SInt))))), preGeneratedSamples = Some(samples)) - testCases( - Seq((ctx, Success(true))), - existingFeature((x: Context) => x.getVar[Boolean](2).get, - "{ (x: Context) => getVar[Boolean](2).get }", - FuncValue(Vector((1, SContext)), OptionGet(GetVar(2.toByte, SOption(SBoolean))))), + verifyCases( + Seq((ctx, Success(Expected(true, cost = 36750)))), + existingFeature((x: Context) => x.getVar[Boolean](11).get, + "{ (x: Context) => getVar[Boolean](11).get }", + FuncValue(Vector((1, SContext)), OptionGet(GetVar(11.toByte, SOption(SBoolean))))), preGeneratedSamples = Some(samples)) } property("xorOf equivalence") { // TODO HF: see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/640 - testCases( - Seq( - (Coll[Boolean](false), Success(false)), - (Coll[Boolean](true), Success(false)), - (Coll[Boolean](false, false), Success(false)), - (Coll[Boolean](false, true), Success(true)), - (Coll[Boolean](true, false), Success(true)), - (Coll[Boolean](true, true), Success(false)), - (Coll[Boolean](false, false, false), Success(false)), - (Coll[Boolean](false, false, true), Success(true)), - (Coll[Boolean](false, true, false), Success(true)), - (Coll[Boolean](false, true, true), Success(true)), - (Coll[Boolean](true, false, false), Success(true)), - (Coll[Boolean](true, false, true), Success(true)), - (Coll[Boolean](true, true, false), Success(true)), - (Coll[Boolean](true, true, true), Success(false)), - (Coll[Boolean](false, false, false, false), Success(false)), - (Coll[Boolean](false, false, false, true), Success(true)), - (Coll[Boolean](false, false, true, false), Success(true)), - (Coll[Boolean](false, false, true, true), Success(true)) - ), + verifyCases( + { + def success[T](v: T, c: Int) = Success(Expected(v, c)) + Seq( + (Coll[Boolean](false), success(false, 37071)), + (Coll[Boolean](true), success(false, 37071)), + (Coll[Boolean](false, false), success(false, 37081)), + (Coll[Boolean](false, true), success(true, 37081)), + (Coll[Boolean](true, false), success(true, 37081)), + (Coll[Boolean](true, true), success(false, 37081)), + (Coll[Boolean](false, false, false), success(false, 37091)), + (Coll[Boolean](false, false, true), success(true, 37091)), + (Coll[Boolean](false, true, false), success(true, 37091)), + (Coll[Boolean](false, true, true), success(true, 37091)), + (Coll[Boolean](true, false, false), success(true, 37091)), + (Coll[Boolean](true, false, true), success(true, 37091)), + (Coll[Boolean](true, true, false), success(true, 37091)), + (Coll[Boolean](true, true, true), success(false, 37091)), + (Coll[Boolean](false, false, false, false), success(false, 37101)), + (Coll[Boolean](false, false, false, true), success(true, 37101)), + (Coll[Boolean](false, false, true, false), success(true, 37101)), + (Coll[Boolean](false, false, true, true), success(true, 37101)) + ) + }, existingFeature((x: Coll[Boolean]) => SigmaDsl.xorOf(x), "{ (x: Coll[Boolean]) => xorOf(x) }", FuncValue(Vector((1, SBooleanArray)), XorOf(ValUse(1, SBooleanArray))))) } property("LogicalNot equivalence") { - testCases( + verifyCases( Seq( - (true, Success(false)), - (false, Success(true))), + (true, Success(Expected(false, 35864))), + (false, Success(Expected(true, 35864)))), existingFeature((x: Boolean) => !x, "{ (x: Boolean) => !x }", - FuncValue(Vector((1, SBoolean)), LogicalNot(ValUse(1, SBoolean)))), true) + FuncValue(Vector((1, SBoolean)), LogicalNot(ValUse(1, SBoolean))))) } property("Numeric Negation equivalence") { - testCases( - Seq( - (Byte.MinValue, Success(Byte.MinValue)), // !!! - (-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))), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36136)) + Seq( + (Byte.MinValue, success(Byte.MinValue)), // !!! + (-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))) + }, existingFeature((x: Byte) => (-x).toByte, "{ (x: Byte) => -x }", FuncValue(Vector((1, SByte)), Negation(ValUse(1, SByte))))) - testCases( - Seq( - (Short.MinValue, Success(Short.MinValue)), // special case! - ((Short.MinValue + 1).toShort, Success(32767.toShort)), - (-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)), - (Short.MaxValue, Success(-32767.toShort))), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36136)) + Seq( + (Short.MinValue, success(Short.MinValue)), // special case! + ((Short.MinValue + 1).toShort, success(32767.toShort)), + (-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)), + (Short.MaxValue, success(-32767.toShort))) + }, existingFeature((x: Short) => (-x).toShort, "{ (x: Short) => -x }", FuncValue(Vector((1, SShort)), Negation(ValUse(1, SShort))))) - testCases( - Seq( - (Int.MinValue, Success(Int.MinValue)), // special case! - (Int.MinValue + 1, Success(2147483647)), - (-63509744, Success(63509744)), - (-1, Success(1)), - (0, Success(0)), - (1, Success(-1)), - (677062351, Success(-677062351)), - (Int.MaxValue, Success(-2147483647))), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36136)) + Seq( + (Int.MinValue, success(Int.MinValue)), // special case! + (Int.MinValue + 1, success(2147483647)), + (-63509744, success(63509744)), + (-1, success(1)), + (0, success(0)), + (1, success(-1)), + (677062351, success(-677062351)), + (Int.MaxValue, success(-2147483647))) + }, existingFeature((x: Int) => -x, "{ (x: Int) => -x }", FuncValue(Vector((1, SInt)), Negation(ValUse(1, SInt))))) - testCases( - Seq( - (Long.MinValue, Success(Long.MinValue)), // special case! - (Long.MinValue + 1, Success(9223372036854775807L)), - (-957264171003115006L, Success(957264171003115006L)), - (-1L, Success(1L)), - (0L, Success(0L)), - (1L, Success(-1L)), - (340835904095777627L, Success(-340835904095777627L)), - (9223372036854775807L, Success(-9223372036854775807L))), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36136)) + Seq( + (Long.MinValue, success(Long.MinValue)), // special case! + (Long.MinValue + 1, success(9223372036854775807L)), + (-957264171003115006L, success(957264171003115006L)), + (-1L, success(1L)), + (0L, success(0L)), + (1L, success(-1L)), + (340835904095777627L, success(-340835904095777627L)), + (9223372036854775807L, success(-9223372036854775807L))) + }, existingFeature((x: Long) => -x, "{ (x: Long) => -x }", FuncValue(Vector((1, SLong)), Negation(ValUse(1, SLong))))) - testCases( - Seq( - (CBigInt(new BigInteger("-1655a05845a6ad363ac88ea21e88b97e436a1f02c548537e12e2d9667bf0680", 16)), Success(CBigInt(new BigInteger("1655a05845a6ad363ac88ea21e88b97e436a1f02c548537e12e2d9667bf0680", 16)))), - (CBigInt(new BigInteger("-1b24ba8badba8abf347cce054d9b9f14f229321507245b8", 16)), Success(CBigInt(new BigInteger("1b24ba8badba8abf347cce054d9b9f14f229321507245b8", 16)))), - (CBigInt(new BigInteger("-1ec9cca2c346cb72a1e65481eaa0627d", 16)), Success(CBigInt(new BigInteger("1ec9cca2c346cb72a1e65481eaa0627d", 16)))), - (CBigInt(new BigInteger("-8000000000000001", 16)), Success(CBigInt(new BigInteger("8000000000000001", 16)))), - (CBigInt(new BigInteger("-8000000000000000", 16)), Success(CBigInt(new BigInteger("8000000000000000", 16)))), - (CBigInt(new BigInteger("-48afe3e059821cd6", 16)), Success(CBigInt(new BigInteger("48afe3e059821cd6", 16)))), - (CBigInt(new BigInteger("-80000001", 16)), Success(CBigInt(new BigInteger("80000001", 16)))), - (CBigInt(new BigInteger("-80000000", 16)), Success(CBigInt(new BigInteger("80000000", 16)))), - (CBigInt(new BigInteger("-1", 16)), Success(CBigInt(new BigInteger("1", 16)))), - (CBigInt(new BigInteger("0", 16)), Success(CBigInt(new BigInteger("0", 16)))), - (CBigInt(new BigInteger("1", 16)), Success(CBigInt(new BigInteger("-1", 16)))), - (CBigInt(new BigInteger("7fffffff", 16)), Success(CBigInt(new BigInteger("-7fffffff", 16)))), - (CBigInt(new BigInteger("80000000", 16)), Success(CBigInt(new BigInteger("-80000000", 16)))), - (CBigInt(new BigInteger("90e8c3b6e8df65c", 16)), Success(CBigInt(new BigInteger("-90e8c3b6e8df65c", 16)))), - (CBigInt(new BigInteger("36aa93288257dcca141d0c01c5cef14c9d1c0f8507872e3fdd839a759636c78", 16)), Success(CBigInt(new BigInteger("-36aa93288257dcca141d0c01c5cef14c9d1c0f8507872e3fdd839a759636c78", 16))))), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36136)) + Seq( + (CBigInt(new BigInteger("-1655a05845a6ad363ac88ea21e88b97e436a1f02c548537e12e2d9667bf0680", 16)), success(CBigInt(new BigInteger("1655a05845a6ad363ac88ea21e88b97e436a1f02c548537e12e2d9667bf0680", 16)))), + (CBigInt(new BigInteger("-1b24ba8badba8abf347cce054d9b9f14f229321507245b8", 16)), success(CBigInt(new BigInteger("1b24ba8badba8abf347cce054d9b9f14f229321507245b8", 16)))), + (CBigInt(new BigInteger("-1ec9cca2c346cb72a1e65481eaa0627d", 16)), success(CBigInt(new BigInteger("1ec9cca2c346cb72a1e65481eaa0627d", 16)))), + (CBigInt(new BigInteger("-8000000000000001", 16)), success(CBigInt(new BigInteger("8000000000000001", 16)))), + (CBigInt(new BigInteger("-8000000000000000", 16)), success(CBigInt(new BigInteger("8000000000000000", 16)))), + (CBigInt(new BigInteger("-48afe3e059821cd6", 16)), success(CBigInt(new BigInteger("48afe3e059821cd6", 16)))), + (CBigInt(new BigInteger("-80000001", 16)), success(CBigInt(new BigInteger("80000001", 16)))), + (CBigInt(new BigInteger("-80000000", 16)), success(CBigInt(new BigInteger("80000000", 16)))), + (CBigInt(new BigInteger("-1", 16)), success(CBigInt(new BigInteger("1", 16)))), + (CBigInt(new BigInteger("0", 16)), success(CBigInt(new BigInteger("0", 16)))), + (CBigInt(new BigInteger("1", 16)), success(CBigInt(new BigInteger("-1", 16)))), + (CBigInt(new BigInteger("7fffffff", 16)), success(CBigInt(new BigInteger("-7fffffff", 16)))), + (CBigInt(new BigInteger("80000000", 16)), success(CBigInt(new BigInteger("-80000000", 16)))), + (CBigInt(new BigInteger("90e8c3b6e8df65c", 16)), success(CBigInt(new BigInteger("-90e8c3b6e8df65c", 16)))), + (CBigInt(new BigInteger("36aa93288257dcca141d0c01c5cef14c9d1c0f8507872e3fdd839a759636c78", 16)), success(CBigInt(new BigInteger("-36aa93288257dcca141d0c01c5cef14c9d1c0f8507872e3fdd839a759636c78", 16))))) + }, existingFeature((x: BigInt) => x.negate(), "{ (x: BigInt) => -x }", FuncValue(Vector((1, SBigInt)), Negation(ValUse(1, SBigInt))))) @@ -3059,10 +3348,13 @@ class SigmaDslSpec extends SigmaDslTesting { suite => property("global functions equivalence") { - testCases( - Seq( - (-1, Success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), - (1, Success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")))), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35981)) + Seq( + (-1, success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), + (1, success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")))) + }, existingFeature({ (x: Int) => SigmaDsl.groupGenerator }, "{ (x: Int) => groupGenerator }", FuncValue( @@ -3075,10 +3367,13 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( - Seq( - (-1, Success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), - (1, Success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")))), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35981)) + Seq( + (-1, success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), + (1, success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")))) + }, existingFeature({ (x: Int) => SigmaDsl.groupGenerator }, "{ (x: Int) => Global.groupGenerator }", FuncValue( @@ -3091,21 +3386,24 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( - Seq( - (CBigInt(new BigInteger("-e5c1a54694c85d644fa30a6fc5f3aa209ed304d57f72683a0ebf21038b6a9d", 16)), Success(Helpers.decodeGroupElement("023395bcba3d7cf21d73c50f8af79d09a8c404c15ce9d04f067d672823bae91a54"))), - (CBigInt(new BigInteger("-bc2d08f935259e0eebf272c66c6e1dbd484c6706390215", 16)), Success(Helpers.decodeGroupElement("02ddcf4c48105faf3c16f7399b5dbedd82ab0bb50ae292d8f88f49a3f86e78974e"))), - (CBigInt(new BigInteger("-35cbe9a7a652e5fe85f735ee9909fdd8", 16)), Success(Helpers.decodeGroupElement("03b110ec9c7a8c20ed873818e976a0e96e5a17be979d3422d59b362de2a3ae043e"))), - (CBigInt(new BigInteger("-3f05ffca6bd4b15c", 16)), Success(Helpers.decodeGroupElement("02acf2657d0714cef8d65ae15c362faa09c0934c0bce872a23398e564c090b85c8"))), - (CBigInt(new BigInteger("-80000001", 16)), Success(Helpers.decodeGroupElement("0391b418fd1778356ce947a5cbb46539fd29842aea168486fae91fc5317177a575"))), - (CBigInt(new BigInteger("-80000000", 16)), Success(Helpers.decodeGroupElement("025318f9b1a2697010c5ac235e9af475a8c7e5419f33d47b18d33feeb329eb99a4"))), - (CBigInt(new BigInteger("-1", 16)), Success(Helpers.decodeGroupElement("0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), - (CBigInt(new BigInteger("0", 16)), Success(Helpers.decodeGroupElement("000000000000000000000000000000000000000000000000000000000000000000"))), - (CBigInt(new BigInteger("1", 16)), Success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), - (CBigInt(new BigInteger("80000000", 16)), Success(Helpers.decodeGroupElement("035318f9b1a2697010c5ac235e9af475a8c7e5419f33d47b18d33feeb329eb99a4"))), - (CBigInt(new BigInteger("1251b7fcd8a01e95", 16)), Success(Helpers.decodeGroupElement("030fde7238b8dddfafab8f5481dc17b880505d6bacbe3cdf2ce975afdcadf66354"))), - (CBigInt(new BigInteger("12f6bd76d8fe1d035bdb14bf2f696e52", 16)), Success(Helpers.decodeGroupElement("028f2ccf13669461cb3cfbea281e2db08fbb67b38493a1628855203d3f69b82763"))), - (CBigInt(new BigInteger("102bb404f5e36bdba004fdefa34df8cfa02e7912f3caf79", 16)), Success(Helpers.decodeGroupElement("03ce82f431d115d45ad555084f8b2861ce5c4561d154e931e9f778594896e46a25")))), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 41237)) + Seq( + (CBigInt(new BigInteger("-e5c1a54694c85d644fa30a6fc5f3aa209ed304d57f72683a0ebf21038b6a9d", 16)), success(Helpers.decodeGroupElement("023395bcba3d7cf21d73c50f8af79d09a8c404c15ce9d04f067d672823bae91a54"))), + (CBigInt(new BigInteger("-bc2d08f935259e0eebf272c66c6e1dbd484c6706390215", 16)), success(Helpers.decodeGroupElement("02ddcf4c48105faf3c16f7399b5dbedd82ab0bb50ae292d8f88f49a3f86e78974e"))), + (CBigInt(new BigInteger("-35cbe9a7a652e5fe85f735ee9909fdd8", 16)), success(Helpers.decodeGroupElement("03b110ec9c7a8c20ed873818e976a0e96e5a17be979d3422d59b362de2a3ae043e"))), + (CBigInt(new BigInteger("-3f05ffca6bd4b15c", 16)), success(Helpers.decodeGroupElement("02acf2657d0714cef8d65ae15c362faa09c0934c0bce872a23398e564c090b85c8"))), + (CBigInt(new BigInteger("-80000001", 16)), success(Helpers.decodeGroupElement("0391b418fd1778356ce947a5cbb46539fd29842aea168486fae91fc5317177a575"))), + (CBigInt(new BigInteger("-80000000", 16)), success(Helpers.decodeGroupElement("025318f9b1a2697010c5ac235e9af475a8c7e5419f33d47b18d33feeb329eb99a4"))), + (CBigInt(new BigInteger("-1", 16)), success(Helpers.decodeGroupElement("0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), + (CBigInt(new BigInteger("0", 16)), success(Helpers.decodeGroupElement("000000000000000000000000000000000000000000000000000000000000000000"))), + (CBigInt(new BigInteger("1", 16)), success(Helpers.decodeGroupElement("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"))), + (CBigInt(new BigInteger("80000000", 16)), success(Helpers.decodeGroupElement("035318f9b1a2697010c5ac235e9af475a8c7e5419f33d47b18d33feeb329eb99a4"))), + (CBigInt(new BigInteger("1251b7fcd8a01e95", 16)), success(Helpers.decodeGroupElement("030fde7238b8dddfafab8f5481dc17b880505d6bacbe3cdf2ce975afdcadf66354"))), + (CBigInt(new BigInteger("12f6bd76d8fe1d035bdb14bf2f696e52", 16)), success(Helpers.decodeGroupElement("028f2ccf13669461cb3cfbea281e2db08fbb67b38493a1628855203d3f69b82763"))), + (CBigInt(new BigInteger("102bb404f5e36bdba004fdefa34df8cfa02e7912f3caf79", 16)), success(Helpers.decodeGroupElement("03ce82f431d115d45ad555084f8b2861ce5c4561d154e931e9f778594896e46a25")))) + }, existingFeature({ (n: BigInt) => SigmaDsl.groupGenerator.exp(n) }, "{ (n: BigInt) => groupGenerator.exp(n) }", FuncValue( @@ -3122,17 +3420,20 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ))) // TODO HF: fix semantics when the left collection is longer - testCases( - 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("0100"), Helpers.decodeBytes("01")), Failure(new ArrayIndexOutOfBoundsException("1"))), - ((Helpers.decodeBytes("800136fe89afff802acea67128a0ff007fffe3498c8001806080012b"), - Helpers.decodeBytes("648018010a5d5800f5b400a580e7b4809b0cd273ff1230bfa800017f7fdb002749b3ac2b86ff")), - Success(Helpers.decodeBytes("e4812eff83f2a780df7aa6d4a8474b80e4f3313a7392313fc8800054"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36903)) + 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("0100"), Helpers.decodeBytes("01")), Failure(new ArrayIndexOutOfBoundsException("1"))), + ((Helpers.decodeBytes("800136fe89afff802acea67128a0ff007fffe3498c8001806080012b"), + Helpers.decodeBytes("648018010a5d5800f5b400a580e7b4809b0cd273ff1230bfa800017f7fdb002749b3ac2b86ff")), + success(Helpers.decodeBytes("e4812eff83f2a780df7aa6d4a8474b80e4f3313a7392313fc8800054"))) + ) + }, existingFeature((x: (Coll[Byte], Coll[Byte])) => SigmaDsl.xor(x._1, x._2), "{ (x: (Coll[Byte], Coll[Byte])) => xor(x._1, x._2) }", FuncValue( @@ -3205,12 +3506,15 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ) - testCases( - Seq( - (Coll[Box](), Success(Coll[Box]())), - (Coll[Box](b1), Success(Coll[Box]())), - (Coll[Box](b1, b2), Success(Coll[Box](b2))) - ), + verifyCases( + { + def success[T](v: T, c: Int) = Success(Expected(v, c)) + Seq( + (Coll[Box](), success(Coll[Box](), 37297)), + (Coll[Box](b1), success(Coll[Box](), 37397)), + (Coll[Box](b1, b2), success(Coll[Box](b2), 37537)) + ) + }, existingFeature({ (x: Coll[Box]) => x.filter({ (b: Box) => b.value > 1 }) }, "{ (x: Coll[Box]) => x.filter({(b: Box) => b.value > 1 }) }", FuncValue( @@ -3222,16 +3526,19 @@ class SigmaDslSpec extends SigmaDslTesting { suite => )), preGeneratedSamples = Some(samples)) - testCases( - Seq( - (Coll[Box](), Success(Coll[Byte]())), - (Coll[Box](b1), Success(Helpers.decodeBytes( - "0008ce02c1a9311ecf1e76c787ba4b1c0e10157b4f6d1e4db3ef0d84f411c99f2d4d2c5b027d1bd9a437e73726ceddecc162e5c85f79aee4798505bc826b8ad1813148e4190257cff6d06fe15d1004596eeb97a7f67755188501e36adc49bd807fe65e9d8281033c6021cff6ba5fdfc4f1742486030d2ebbffd9c9c09e488792f3102b2dcdabd5" - ))), - (Coll[Box](b1, b2), Success(Helpers.decodeBytes( - "0008ce02c1a9311ecf1e76c787ba4b1c0e10157b4f6d1e4db3ef0d84f411c99f2d4d2c5b027d1bd9a437e73726ceddecc162e5c85f79aee4798505bc826b8ad1813148e4190257cff6d06fe15d1004596eeb97a7f67755188501e36adc49bd807fe65e9d8281033c6021cff6ba5fdfc4f1742486030d2ebbffd9c9c09e488792f3102b2dcdabd500d197830201010096850200" - ))) - ), + verifyCases( + { + def success[T](v: T, c: Int) = Success(Expected(v, c)) + Seq( + (Coll[Box](), success(Coll[Byte](), 38126)), + (Coll[Box](b1), success(Helpers.decodeBytes( + "0008ce02c1a9311ecf1e76c787ba4b1c0e10157b4f6d1e4db3ef0d84f411c99f2d4d2c5b027d1bd9a437e73726ceddecc162e5c85f79aee4798505bc826b8ad1813148e4190257cff6d06fe15d1004596eeb97a7f67755188501e36adc49bd807fe65e9d8281033c6021cff6ba5fdfc4f1742486030d2ebbffd9c9c09e488792f3102b2dcdabd5" + ), 38206)), + (Coll[Box](b1, b2), success(Helpers.decodeBytes( + "0008ce02c1a9311ecf1e76c787ba4b1c0e10157b4f6d1e4db3ef0d84f411c99f2d4d2c5b027d1bd9a437e73726ceddecc162e5c85f79aee4798505bc826b8ad1813148e4190257cff6d06fe15d1004596eeb97a7f67755188501e36adc49bd807fe65e9d8281033c6021cff6ba5fdfc4f1742486030d2ebbffd9c9c09e488792f3102b2dcdabd500d197830201010096850200" + ), 38286)) + ) + }, existingFeature({ (x: Coll[Box]) => x.flatMap({ (b: Box) => b.propositionBytes }) }, "{ (x: Coll[Box]) => x.flatMap({(b: Box) => b.propositionBytes }) }", FuncValue( @@ -3247,12 +3554,15 @@ class SigmaDslSpec extends SigmaDslTesting { suite => )), preGeneratedSamples = Some(samples)) - testCases( - Seq( - (Coll[Box](), Success(Coll[(Box, Box)]())), - (Coll[Box](b1), Success(Coll[(Box, Box)]((b1, b1)))), - (Coll[Box](b1, b2), Success(Coll[(Box, Box)]((b1, b1), (b2, b2)))) - ), + verifyCases( + { + def success[T](v: T, c: Int) = Success(Expected(v, c)) + 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)) + ) + }, existingFeature({ (x: Coll[Box]) => x.zip(x) }, "{ (x: Coll[Box]) => x.zip(x) }", FuncValue( @@ -3268,23 +3578,29 @@ class SigmaDslSpec extends SigmaDslTesting { suite => )), preGeneratedSamples = Some(samples)) - testCases( - Seq( - (Coll[Box](), Success(0)), - (Coll[Box](b1), Success(1)), - (Coll[Box](b1, b2), Success(2)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35954)) + Seq( + (Coll[Box](), success(0)), + (Coll[Box](b1), success(1)), + (Coll[Box](b1, b2), success(2)) + ) + }, existingFeature({ (x: Coll[Box]) => x.size }, "{ (x: Coll[Box]) => x.size }", FuncValue(Vector((1, SCollectionType(SBox))), SizeOf(ValUse(1, SCollectionType(SBox))))), preGeneratedSamples = Some(samples)) - testCases( - Seq( - (Coll[Box](), Success(Coll[Int]())), - (Coll[Box](b1), Success(Coll[Int](0))), - (Coll[Box](b1, b2), Success(Coll[Int](0, 1))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36036)) + Seq( + (Coll[Box](), success(Coll[Int]())), + (Coll[Box](b1), success(Coll[Int](0))), + (Coll[Box](b1, b2), success(Coll[Int](0, 1))) + ) + }, existingFeature({ (x: Coll[Box]) => x.indices }, "{ (x: Coll[Box]) => x.indices }", FuncValue( @@ -3298,12 +3614,15 @@ class SigmaDslSpec extends SigmaDslTesting { suite => )), preGeneratedSamples = Some(samples)) - testCases( - Seq( - (Coll[Box](), Success(true)), - (Coll[Box](b1), Success(false)), - (Coll[Box](b1, b2), Success(false)) - ), + verifyCases( + { + def success[T](v: T, c: Int) = Success(Expected(v, c)) + Seq( + (Coll[Box](), success(true, 37909)), + (Coll[Box](b1), success(false, 37969)), + (Coll[Box](b1, b2), success(false, 38029)) + ) + }, existingFeature({ (x: Coll[Box]) => x.forall({ (b: Box) => b.value > 1 }) }, "{ (x: Coll[Box]) => x.forall({(b: Box) => b.value > 1 }) }", FuncValue( @@ -3315,12 +3634,15 @@ class SigmaDslSpec extends SigmaDslTesting { suite => )), preGeneratedSamples = Some(samples)) - testCases( - Seq( - (Coll[Box](), Success(false)), - (Coll[Box](b1), Success(false)), - (Coll[Box](b1, b2), Success(true)) - ), + verifyCases( + { + def success[T](v: T, c: Int) = Success(Expected(v, c)) + Seq( + (Coll[Box](), success(false, 38455)), + (Coll[Box](b1), success(false, 38515)), + (Coll[Box](b1, b2), success(true, 38575)) + ) + }, existingFeature({ (x: Coll[Box]) => x.exists({ (b: Box) => b.value > 1 }) }, "{ (x: Coll[Box]) => x.exists({(b: Box) => b.value > 1 }) }", FuncValue( @@ -3339,23 +3661,26 @@ class SigmaDslSpec extends SigmaDslTesting { suite => r <- Gen.choose(l, arr.length - 1) } yield (arr, (l, r)) property("Coll flatMap method equivalence") { - testCases( - Seq( - Coll[GroupElement]() -> Success(Coll[Byte]()), - Coll[GroupElement]( - Helpers.decodeGroupElement("02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee587"), - Helpers.decodeGroupElement("0390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa")) -> - Success(Helpers.decodeBytes( - "02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee5870390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa" - )), - Coll[GroupElement]( - Helpers.decodeGroupElement("02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee587"), - Helpers.decodeGroupElement("0390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa"), - Helpers.decodeGroupElement("03bd839b969b02d218fd1192f2c80cbda9c6ce9c7ddb765f31b748f4666203df85")) -> - Success(Helpers.decodeBytes( - "02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee5870390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa03bd839b969b02d218fd1192f2c80cbda9c6ce9c7ddb765f31b748f4666203df85" - )) - ), + verifyCases( + { + def success[T](v: T, c: Int) = Success(Expected(v, c)) + Seq( + Coll[GroupElement]() -> success(Coll[Byte](), 40133), + Coll[GroupElement]( + Helpers.decodeGroupElement("02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee587"), + Helpers.decodeGroupElement("0390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa")) -> + success(Helpers.decodeBytes( + "02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee5870390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa" + ), 40213), + Coll[GroupElement]( + Helpers.decodeGroupElement("02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee587"), + Helpers.decodeGroupElement("0390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa"), + Helpers.decodeGroupElement("03bd839b969b02d218fd1192f2c80cbda9c6ce9c7ddb765f31b748f4666203df85")) -> + success(Helpers.decodeBytes( + "02d65904820f8330218cf7318b3810d0c9ab9df86f1ee6100882683f23c0aee5870390e9daa9916f30d0bc61a8e381c6005edfb7938aee5bb4fc9e8a759c7748ffaa03bd839b969b02d218fd1192f2c80cbda9c6ce9c7ddb765f31b748f4666203df85" + ), 40253) + ) + }, existingFeature( { (x: Coll[GroupElement]) => x.flatMap({ (b: GroupElement) => b.getEncoded }) }, "{ (x: Coll[GroupElement]) => x.flatMap({ (b: GroupElement) => b.getEncoded }) }", @@ -3395,21 +3720,24 @@ class SigmaDslSpec extends SigmaDslTesting { suite => property("Coll patch method equivalence") { val samples = genSamples(collWithRangeGen, MinSuccessful(50)) - testCases( - 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))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 37514)) + 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))) + ) + }, existingFeature( { (x: (Coll[Int], (Int, Int))) => val coll = x._1 @@ -3459,18 +3787,21 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("Coll updated method equivalence") { - testCases( + verifyCases( // (coll, (index, elem)) - Seq( - ((Coll[Int](), (0, 0)), Failure(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, 2), (2, 0)), Failure(new IndexOutOfBoundsException("2"))), - ((Coll[Int](1, 2), (3, 0)), Failure(new IndexOutOfBoundsException("3"))), - ((Coll[Int](1, 2), (-1, 0)), Failure(new IndexOutOfBoundsException("-1"))) - ), + { + def success[T](v: T) = Success(Expected(v, 37180)) + Seq( + ((Coll[Int](), (0, 0)), Failure(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, 2), (2, 0)), Failure(new IndexOutOfBoundsException("2"))), + ((Coll[Int](1, 2), (3, 0)), Failure(new IndexOutOfBoundsException("3"))), + ((Coll[Int](1, 2), (-1, 0)), Failure(new IndexOutOfBoundsException("-1"))) + ) + }, existingFeature( (x: (Coll[Int], (Int, Int))) => x._1.updated(x._2._1, x._2._2), "{ (x: (Coll[Int], (Int, Int))) => x._1.updated(x._2._1, x._2._2) }", @@ -3512,26 +3843,29 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } yield (coll, (is.toColl, vs)), MinSuccessful(20)) - testCases( + verifyCases( // (coll, (indexes, values)) - Seq( - ((Coll[Int](), (Coll(0), Coll(0))), Failure(new IndexOutOfBoundsException("0"))), - ((Coll[Int](), (Coll(0, 1), Coll(0, 0))), Failure(new IndexOutOfBoundsException("0"))), - ((Coll[Int](), (Coll(0, 1), Coll(0))), Failure(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, 1), Coll(0, 0))), Failure(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, 1, 2), Coll(0, 0, 0))), Failure(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(2), Coll(0))), Failure(new IndexOutOfBoundsException("2"))), - ((Coll[Int](1, 2), (Coll(3), Coll(0))), Failure(new IndexOutOfBoundsException("3"))), - ((Coll[Int](1, 2), (Coll(-1), Coll(0))), Failure(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))) - ), + { + def success[T](v: T) = Success(Expected(v, 37817)) + Seq( + ((Coll[Int](), (Coll(0), Coll(0))), Failure(new IndexOutOfBoundsException("0"))), + ((Coll[Int](), (Coll(0, 1), Coll(0, 0))), Failure(new IndexOutOfBoundsException("0"))), + ((Coll[Int](), (Coll(0, 1), Coll(0))), Failure(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, 1), Coll(0, 0))), Failure(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, 1, 2), Coll(0, 0, 0))), Failure(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(2), Coll(0))), Failure(new IndexOutOfBoundsException("2"))), + ((Coll[Int](1, 2), (Coll(3), Coll(0))), Failure(new IndexOutOfBoundsException("3"))), + ((Coll[Int](1, 2), (Coll(-1), Coll(0))), Failure(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))) + ) + }, existingFeature( (x: (Coll[Int], (Coll[Int], Coll[Int]))) => x._1.updateMany(x._2._1, x._2._2), "{ (x: (Coll[Int], (Coll[Int], Coll[Int]))) => x._1.updateMany(x._2._1, x._2._2) }", @@ -3606,19 +3940,22 @@ class SigmaDslSpec extends SigmaDslTesting { suite => property("Coll fold method equivalence") { val n = ExactNumeric.IntIsExactNumeric - testCases( + verifyCases( // (coll, initState) - Seq( - ((Coll[Byte](), 0), Success(0)), - ((Coll[Byte](), Int.MaxValue), Success(Int.MaxValue)), - ((Coll[Byte](1), Int.MaxValue - 1), Success(Int.MaxValue)), - ((Coll[Byte](1), Int.MaxValue), Failure(new ArithmeticException("integer overflow"))), - ((Coll[Byte](-1), Int.MinValue + 1), Success(Int.MinValue)), - ((Coll[Byte](-1), Int.MinValue), Failure(new ArithmeticException("integer overflow"))), - ((Coll[Byte](1, 2), 0), Success(3)), - ((Coll[Byte](1, -1), 0), Success(0)), - ((Coll[Byte](1, -1, 1), 0), Success(1)) - ), + { + def success[T](v: T, c: Int) = Success(Expected(v, c)) + 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](1), Int.MaxValue), Failure(new ArithmeticException("integer overflow"))), + ((Coll[Byte](-1), Int.MinValue + 1), success(Int.MinValue, 41396)), + ((Coll[Byte](-1), Int.MinValue), Failure(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)) + ) + }, 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 }) }", @@ -3640,28 +3977,31 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("Coll indexOf method equivalence") { - testCases( + verifyCases( // (coll, (elem: Byte, from: Int)) - 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)) - ), + { + def success[T](v: T) = Success(Expected(v, 37649)) + 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)) + ) + }, existingFeature( { (x: (Coll[Byte], (Byte, Int))) => x._1.indexOf(x._2._1, x._2._2) }, "{ (x: (Coll[Byte], (Byte, Int))) => x._1.indexOf(x._2._1, x._2._2) }", @@ -3692,17 +4032,20 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("Coll apply method equivalence") { - testCases( - Seq( - ((Coll[Int](), 0), Failure(new ArrayIndexOutOfBoundsException("0"))), - ((Coll[Int](), -1), Failure(new ArrayIndexOutOfBoundsException("-1"))), - ((Coll[Int](1), 0), Success(1)), - ((Coll[Int](1), 1), Failure(new ArrayIndexOutOfBoundsException("1"))), - ((Coll[Int](1), -1), Failure(new ArrayIndexOutOfBoundsException("-1"))), - ((Coll[Int](1, 2), 1), Success(2)), - ((Coll[Int](1, 2), 1), Success(2)), - ((Coll[Int](1, 2), 2), Failure(new ArrayIndexOutOfBoundsException("2"))) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36410)) + Seq( + ((Coll[Int](), 0), Failure(new ArrayIndexOutOfBoundsException("0"))), + ((Coll[Int](), -1), Failure(new ArrayIndexOutOfBoundsException("-1"))), + ((Coll[Int](1), 0), success(1)), + ((Coll[Int](1), 1), Failure(new ArrayIndexOutOfBoundsException("1"))), + ((Coll[Int](1), -1), Failure(new ArrayIndexOutOfBoundsException("-1"))), + ((Coll[Int](1, 2), 1), success(2)), + ((Coll[Int](1, 2), 1), success(2)), + ((Coll[Int](1, 2), 2), Failure(new ArrayIndexOutOfBoundsException("2"))) + ) + }, existingFeature((x: (Coll[Int], Int)) => x._1(x._2), "{ (x: (Coll[Int], Int)) => x._1(x._2) }", FuncValue( @@ -3720,19 +4063,22 @@ class SigmaDslSpec extends SigmaDslTesting { suite => property("Coll getOrElse method equivalence") { val default = 10 - testCases( + verifyCases( // (coll, (index, default)) - Seq( - ((Coll[Int](), (0, default)), Success(default)), - ((Coll[Int](), (-1, default)), Success(default)), - ((Coll[Int](1), (0, default)), Success(1)), - ((Coll[Int](1), (1, default)), Success(default)), - ((Coll[Int](1), (-1, default)), Success(default)), - ((Coll[Int](1, 2), (0, default)), Success(1)), - ((Coll[Int](1, 2), (1, default)), Success(2)), - ((Coll[Int](1, 2), (2, default)), Success(default)), - ((Coll[Int](1, 2), (-1, default)), Success(default)) - ), + { + def success[T](v: T) = Success(Expected(v, 37020)) + Seq( + ((Coll[Int](), (0, default)), success(default)), + ((Coll[Int](), (-1, default)), success(default)), + ((Coll[Int](1), (0, default)), success(1)), + ((Coll[Int](1), (1, default)), success(default)), + ((Coll[Int](1), (-1, default)), success(default)), + ((Coll[Int](1, 2), (0, default)), success(1)), + ((Coll[Int](1, 2), (1, default)), success(2)), + ((Coll[Int](1, 2), (2, default)), success(default)), + ((Coll[Int](1, 2), (-1, default)), success(default)) + ) + }, existingFeature((x: (Coll[Int], (Int, Int))) => x._1.getOrElse(x._2._1, x._2._2), "{ (x: (Coll[Int], (Int, Int))) => x._1.getOrElse(x._2._1, x._2._2) }", FuncValue( @@ -3761,11 +4107,14 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("Tuple size method equivalence") { - testCases( - Seq( - ((0, 0), Success(2)), - ((1, 2), Success(2)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 35905)) + Seq( + ((0, 0), success(2)), + ((1, 2), success(2)) + ) + }, existingFeature((x: (Int, Int)) => 2, "{ (x: (Int, Int)) => x.size }", FuncValue(Vector((1, SPair(SInt, SInt))), IntConstant(2)))) @@ -3773,8 +4122,8 @@ class SigmaDslSpec extends SigmaDslTesting { suite => property("Tuple apply method equivalence") { val samples = genSamples[(Int, Int)](DefaultMinSuccessful) - testCases( - Seq(((1, 2), Success(1))), + verifyCases( + Seq(((1, 2), Success(Expected(1, cost = 36013)))), existingFeature((x: (Int, Int)) => x._1, "{ (x: (Int, Int)) => x(0) }", FuncValue( @@ -3782,8 +4131,8 @@ class SigmaDslSpec extends SigmaDslTesting { suite => SelectField.typed[Value[SInt.type]](ValUse(1, SPair(SInt, SInt)), 1.toByte) )), preGeneratedSamples = Some(samples)) - testCases( - Seq(((1, 2), Success(2))), + verifyCases( + Seq(((1, 2), Success(Expected(2, cost = 36013)))), existingFeature((x: (Int, Int)) => x._2, "{ (x: (Int, Int)) => x(1) }", FuncValue( @@ -3795,13 +4144,16 @@ class SigmaDslSpec extends SigmaDslTesting { suite => property("Coll map method equivalence") { val n = ExactNumeric.IntIsExactNumeric - testCases( - Seq( - (Coll[Int](), Success(Coll[Int]())), - (Coll[Int](1), Success(Coll[Int](2))), - (Coll[Int](1, 2), Success(Coll[Int](2, 3))), - (Coll[Int](1, 2, Int.MaxValue), Failure(new ArithmeticException("integer overflow"))) - ), + verifyCases( + { + def success[T](v: T, c: Int) = Success(Expected(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](1, 2, Int.MaxValue), Failure(new ArithmeticException("integer overflow"))) + ) + }, existingFeature((x: Coll[Int]) => x.map({ (v: Int) => n.plus(v, 1) }), "{ (x: Coll[Int]) => x.map({ (v: Int) => v + 1 }) }", FuncValue( @@ -3815,20 +4167,23 @@ class SigmaDslSpec extends SigmaDslTesting { suite => property("Coll slice method equivalence") { val samples = genSamples(collWithRangeGen, DefaultMinSuccessful) - testCases( + verifyCases( // (coll, (from, until)) - 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))) - ), + { + def success[T](v: T) = Success(Expected(v, 36964)) + 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))) + ) + }, 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) }", FuncValue( @@ -3858,16 +4213,19 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("Coll append method equivalence") { - testCases( - 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)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 37765)) + 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)) + ) + }, existingFeature( { (x: (Coll[Int], Coll[Int])) => x._1.append(x._2) }, "{ (x: (Coll[Int], Coll[Int])) => x._1.append(x._2) }", @@ -3887,35 +4245,37 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("Option methods equivalence") { - testCases( + def success[T](v: T, c: Int) = Success(Expected(v, c)) + + verifyCases( Seq( (None -> Failure(new NoSuchElementException("None.get"))), - (Some(10L) -> Success(10L))), + (Some(10L) -> success(10L, 36046))), existingFeature({ (x: Option[Long]) => x.get }, "{ (x: Option[Long]) => x.get }", FuncValue(Vector((1, SOption(SLong))), OptionGet(ValUse(1, SOption(SLong)))))) - testCases( + verifyCases( Seq( - (None -> Success(false)), - (Some(10L) -> Success(true))), + (None -> success(false, 36151)), + (Some(10L) -> success(true, 36151))), existingFeature({ (x: Option[Long]) => x.isDefined }, "{ (x: Option[Long]) => x.isDefined }", FuncValue(Vector((1, SOption(SLong))), OptionIsDefined(ValUse(1, SOption(SLong)))))) - testCases( + verifyCases( Seq( - (None -> Success(1L)), - (Some(10L) -> Success(10L))), + (None -> success(1L, 36367)), + (Some(10L) -> success(10L, 36367))), 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))))) - testCases( + verifyCases( Seq( - (None -> Success(None)), - (Some(10L) -> Success(None)), - (Some(1L) -> Success(Some(1L)))), + (None -> success(None, 38239)), + (Some(10L) -> success(None, 38239)), + (Some(1L) -> success(Some(1L), 38239))), existingFeature({ (x: Option[Long]) => x.filter({ (v: Long) => v == 1} ) }, "{ (x: Option[Long]) => x.filter({ (v: Long) => v == 1 }) }", FuncValue( @@ -3929,10 +4289,10 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ))) val n = ExactNumeric.LongIsExactNumeric - testCases( + verifyCases( Seq( - (None -> Success(None)), - (Some(10L) -> Success(Some(11L))), + (None -> success(None, 38575)), + (Some(10L) -> success(Some(11L), 38575)), (Some(Long.MaxValue) -> Failure(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 }) }", @@ -3970,13 +4330,13 @@ class SigmaDslSpec extends SigmaDslTesting { suite => property("Option fold workaround method") { val n = ExactNumeric.LongIsExactNumeric - testCases( + verifyCases( Seq( - (None -> Success(5L)), - (Some(0L) -> Success(1L)), + (None -> Failure(new NoSuchElementException("None.get"))), + (Some(0L) -> Success(Expected(1L, 39012))), (Some(Long.MaxValue) -> Failure(new ArithmeticException("long overflow"))) ), - existingFeature({ (x: Option[Long]) => x.fold(5.toLong)( (v: Long) => n.plus(v, 1) ) }, + existingFeature({ (x: Option[Long]) => x.fold(throw new NoSuchElementException("None.get"))( (v: Long) => n.plus(v, 1) ) }, """{(x: Option[Long]) => | def f(opt: Long): Long = opt + 1 | if (x.isDefined) f(x.get) else 5L @@ -3998,21 +4358,33 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("blake2b256, sha256 equivalence") { - testCases( + def success[T](v: T, c: Int) = Success(Expected(v, c)) + + verifyCases( Seq( - Coll[Byte]() -> Success(Helpers.decodeBytes("0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8")), + Coll[Byte]() -> + success( + Helpers.decodeBytes("0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8"), + 36269), Helpers.decodeBytes("e0ff0105ffffac31010017ff33") -> - Success(Helpers.decodeBytes("33707eed9aab64874ff2daa6d6a378f61e7da36398fb36c194c7562c9ff846b5")) + success( + Helpers.decodeBytes("33707eed9aab64874ff2daa6d6a378f61e7da36398fb36c194c7562c9ff846b5"), + 36269) ), existingFeature((x: Coll[Byte]) => SigmaDsl.blake2b256(x), "{ (x: Coll[Byte]) => blake2b256(x) }", FuncValue(Vector((1, SByteArray)), CalcBlake2b256(ValUse(1, SByteArray))))) - testCases( + verifyCases( Seq( - Coll[Byte]() -> Success(Helpers.decodeBytes("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")), + Coll[Byte]() -> + success( + Helpers.decodeBytes("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), + 36393), Helpers.decodeBytes("e0ff0105ffffac31010017ff33") -> - Success(Helpers.decodeBytes("367d0ec2cdc14aac29d5beb60c2bfc86d5a44a246308659af61c1b85fa2ca2cc")) + success( + Helpers.decodeBytes("367d0ec2cdc14aac29d5beb60c2bfc86d5a44a246308659af61c1b85fa2ca2cc"), + 36393) ), existingFeature((x: Coll[Byte]) => SigmaDsl.sha256(x), "{ (x: Coll[Byte]) => sha256(x) }", @@ -4024,17 +4396,19 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("sigmaProp equivalence") { - testCases( + verifyCases( Seq( - (false, Success(CSigmaProp(TrivialProp.FalseProp))), - (true, Success(CSigmaProp(TrivialProp.TrueProp)))), + (false, Success(Expected(CSigmaProp(TrivialProp.FalseProp), 35892))), + (true, Success(Expected(CSigmaProp(TrivialProp.TrueProp), 35892)))), existingFeature((x: Boolean) => sigmaProp(x), "{ (x: Boolean) => sigmaProp(x) }", FuncValue(Vector((1, SBoolean)), BoolToSigmaProp(ValUse(1, SBoolean))))) } property("atLeast equivalence") { - testCases( + def success[T](v: T) = Success(Expected(v, 36462)) + + verifyCases( Seq( Coll[SigmaProp]( CSigmaProp( @@ -4044,7 +4418,7 @@ class SigmaDslSpec extends SigmaDslTesting { suite => Helpers.decodeECPoint("02614b14a8c6c6b4b7ce017d72fbca7f9218b72c16bdd88f170ffb300b106b9014"), Helpers.decodeECPoint("034cc5572276adfa3e283a3f1b0f0028afaadeaa362618c5ec43262d8cefe7f004") ) - )) -> Success(CSigmaProp(TrivialProp.TrueProp)), + )) -> success(CSigmaProp(TrivialProp.TrueProp)), Coll[SigmaProp]( CSigmaProp( ProveDHTuple( @@ -4056,7 +4430,7 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ), CSigmaProp(ProveDlog(Helpers.decodeECPoint("03f7eacae7476a9ef082513a6a70ed6b208aafad0ade5f614ac6cfa2176edd0d69"))), CSigmaProp(ProveDlog(Helpers.decodeECPoint("023bddd50b917388cd2c4f478f3ea9281bf03a252ee1fefe9c79f800afaa8d86ad"))) - ) -> Success( + ) -> success( CSigmaProp( CTHRESHOLD( 2, @@ -4088,33 +4462,37 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("&& sigma equivalence") { - testCases( - Seq( - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798"))), - CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - Success( - CSigmaProp( - CAND( - Seq( - ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798")), - ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")) + + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36428)) + Seq( + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798"))), + CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> + success( + CSigmaProp( + CAND( + Seq( + ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798")), + ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")) + ) ) ) - ) - ), - (CSigmaProp(TrivialProp.TrueProp), - CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - Success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), - (CSigmaProp(TrivialProp.FalseProp), - CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - Success(CSigmaProp(TrivialProp.FalseProp)), - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), - CSigmaProp(TrivialProp.TrueProp)) -> - Success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), - CSigmaProp(TrivialProp.FalseProp)) -> - Success(CSigmaProp(TrivialProp.FalseProp)) - ), + ), + (CSigmaProp(TrivialProp.TrueProp), + CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + (CSigmaProp(TrivialProp.FalseProp), + CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> + success(CSigmaProp(TrivialProp.FalseProp)), + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), + CSigmaProp(TrivialProp.TrueProp)) -> + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), + CSigmaProp(TrivialProp.FalseProp)) -> + success(CSigmaProp(TrivialProp.FalseProp)) + ) + }, existingFeature( (x: (SigmaProp, SigmaProp)) => x._1 && x._2, "{ (x:(SigmaProp, SigmaProp)) => x._1 && x._2 }", @@ -4128,13 +4506,16 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( - Seq( - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), true) -> - Success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), false) -> - Success(CSigmaProp(TrivialProp.FalseProp)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36522)) + Seq( + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), true) -> + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), false) -> + success(CSigmaProp(TrivialProp.FalseProp)) + ) + }, existingFeature( (x: (SigmaProp, Boolean)) => x._1 && sigmaProp(x._2), "{ (x:(SigmaProp, Boolean)) => x._1 && sigmaProp(x._2) }", @@ -4152,33 +4533,36 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("|| sigma equivalence") { - testCases( - Seq( - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798"))), - CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - Success( - CSigmaProp( - COR( - Seq( - ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798")), - ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")) + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36494)) + Seq( + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798"))), + CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> + success( + CSigmaProp( + COR( + Seq( + ProveDlog(Helpers.decodeECPoint("02ea9bf6da7f512386c6ca509d40f8c5e7e0ffb3eea5dc3c398443ea17f4510798")), + ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")) + ) ) ) - ) - ), - (CSigmaProp(TrivialProp.FalseProp), - CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - Success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), - (CSigmaProp(TrivialProp.TrueProp), - CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> - Success(CSigmaProp(TrivialProp.TrueProp)), - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), - CSigmaProp(TrivialProp.FalseProp)) -> - Success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), - CSigmaProp(TrivialProp.TrueProp)) -> - Success(CSigmaProp(TrivialProp.TrueProp)) - ), + ), + (CSigmaProp(TrivialProp.FalseProp), + CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + (CSigmaProp(TrivialProp.TrueProp), + CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))) -> + success(CSigmaProp(TrivialProp.TrueProp)), + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), + CSigmaProp(TrivialProp.FalseProp)) -> + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), + CSigmaProp(TrivialProp.TrueProp)) -> + success(CSigmaProp(TrivialProp.TrueProp)) + ) + }, existingFeature( (x: (SigmaProp, SigmaProp)) => x._1 || x._2, "{ (x:(SigmaProp, SigmaProp)) => x._1 || x._2 }", @@ -4192,13 +4576,16 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ) ))) - testCases( - Seq( - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), false) -> - Success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), - (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), true) -> - Success(CSigmaProp(TrivialProp.TrueProp)) - ), + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 36588)) + Seq( + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), false) -> + success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606")))), + (CSigmaProp(ProveDlog(Helpers.decodeECPoint("03a426a66fc1af2792b35d9583904c3fb877b49ae5cea45b7a2aa105ffa4c68606"))), true) -> + success(CSigmaProp(TrivialProp.TrueProp)) + ) + }, existingFeature( (x: (SigmaProp, Boolean)) => x._1 || sigmaProp(x._2), "{ (x:(SigmaProp, Boolean)) => x._1 || sigmaProp(x._2) }", @@ -4216,10 +4603,12 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("SigmaProp.propBytes equivalence") { - testCases( + verifyCases( Seq( - CSigmaProp(ProveDlog(Helpers.decodeECPoint("039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6f"))) -> - Success(Helpers.decodeBytes("0008cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6f")) + CSigmaProp(ProveDlog(Helpers.decodeECPoint("039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6f"))) + -> Success(Expected( + Helpers.decodeBytes("0008cd039d0b1e46c21540d033143440d2fb7dd5d650cf89981c99ee53c6e0374d2b1b6f"), + cost = 35902)) ), existingFeature((x: SigmaProp) => x.propBytes, "{ (x: SigmaProp) => x.propBytes }", @@ -4245,19 +4634,21 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("allOf equivalence") { - testCases( + def success[T](v: T, c: Int) = Success(Expected(v, c)) + + verifyCases( Seq( - (Coll[Boolean]() -> Success(true)), - (Coll[Boolean](true) -> Success(true)), - (Coll[Boolean](false) -> Success(false)), - (Coll[Boolean](false, false) -> Success(false)), - (Coll[Boolean](false, true) -> Success(false)), - (Coll[Boolean](true, false) -> Success(false)), - (Coll[Boolean](true, true) -> Success(true)), - (Coll[Boolean](true, false, false) -> Success(false)), - (Coll[Boolean](true, false, true) -> Success(false)), - (Coll[Boolean](true, true, false) -> Success(false)), - (Coll[Boolean](true, true, true) -> Success(true)) + (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)) ), existingFeature((x: Coll[Boolean]) => SigmaDsl.allOf(x), "{ (x: Coll[Boolean]) => allOf(x) }", @@ -4265,19 +4656,21 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("anyOf equivalence") { - testCases( + def success[T](v: T, c: Int) = Success(Expected(v, c)) + + verifyCases( Seq( - (Coll[Boolean]() -> Success(false)), - (Coll[Boolean](true) -> Success(true)), - (Coll[Boolean](false) -> Success(false)), - (Coll[Boolean](false, false) -> Success(false)), - (Coll[Boolean](false, true) -> Success(true)), - (Coll[Boolean](true, false) -> Success(true)), - (Coll[Boolean](true, true) -> Success(true)), - (Coll[Boolean](true, false, false) -> Success(true)), - (Coll[Boolean](true, false, true) -> Success(true)), - (Coll[Boolean](true, true, false) -> Success(true)), - (Coll[Boolean](true, true, true) -> Success(true)) + (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)) ), existingFeature((x: Coll[Boolean]) => SigmaDsl.anyOf(x), "{ (x: Coll[Boolean]) => anyOf(x) }", @@ -4285,10 +4678,12 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("proveDlog equivalence") { - testCases( + verifyCases( Seq( - (Helpers.decodeGroupElement("02288f0e55610c3355c89ed6c5de43cf20da145b8c54f03a29f481e540d94e9a69") -> - Success(CSigmaProp(ProveDlog(Helpers.decodeECPoint("02288f0e55610c3355c89ed6c5de43cf20da145b8c54f03a29f481e540d94e9a69"))))) + (Helpers.decodeGroupElement("02288f0e55610c3355c89ed6c5de43cf20da145b8c54f03a29f481e540d94e9a69") + -> Success(Expected( + CSigmaProp(ProveDlog(Helpers.decodeECPoint("02288f0e55610c3355c89ed6c5de43cf20da145b8c54f03a29f481e540d94e9a69"))), + cost = 45935))) ), existingFeature({ (x: GroupElement) => SigmaDsl.proveDlog(x) }, "{ (x: GroupElement) => proveDlog(x) }", @@ -4296,18 +4691,20 @@ class SigmaDslSpec extends SigmaDslTesting { suite => } property("proveDHTuple equivalence") { - testCases( + verifyCases( Seq( - (Helpers.decodeGroupElement("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a") -> Success( - CSigmaProp( - ProveDHTuple( - Helpers.decodeECPoint("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a"), - Helpers.decodeECPoint("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a"), - Helpers.decodeECPoint("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a"), - Helpers.decodeECPoint("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a") - ) - ) - )) + (Helpers.decodeGroupElement("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a") + -> Success(Expected( + CSigmaProp( + ProveDHTuple( + Helpers.decodeECPoint("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a"), + Helpers.decodeECPoint("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a"), + Helpers.decodeECPoint("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a"), + Helpers.decodeECPoint("039c15221a318d27c186eba84fa8d986c1f63bbd9f8060380c9bfc2ef455d8346a") + ) + ), + cost = 76215 + ))) ), existingFeature({ (x: GroupElement) => SigmaDsl.proveDHTuple(x, x, x, x) }, "{ (x: GroupElement) => proveDHTuple(x, x, x, x) }", @@ -4334,23 +4731,27 @@ class SigmaDslSpec extends SigmaDslTesting { suite => ErgoTree.ConstantSegregationHeader, Vector(IntConstant(10)), BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), IntConstant(20)))) - testCases( - Seq( - (Helpers.decodeBytes(""), 0) -> Failure(new java.nio.BufferUnderflowException()), - - // TODO HF: fix for trees without segregation flag - // NOTE: constants count is serialized erroneously in the following 2 cases - (Coll(t1.bytes:_*), 0) -> Success(Helpers.decodeBytes("000008d3")), - (Helpers.decodeBytes("000008d3"), 0) -> Success(Helpers.decodeBytes("00000008d3")), - // tree with segregation flag, empty constants array - (Coll(t2.bytes:_*), 0) -> Success(Helpers.decodeBytes("100008d3")), - (Helpers.decodeBytes("100008d3"), 0) -> Success(Helpers.decodeBytes("100008d3")), - // 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(t4.bytes:_*), 0) -> Failure(new AssertionError("assertion failed: expected new constant to have the same SInt$ tpe, got SSigmaProp")) - ), + + verifyCases( + { + def success[T](v: T) = Success(Expected(v, 37694)) + Seq( + (Helpers.decodeBytes(""), 0) -> Failure(new java.nio.BufferUnderflowException()), + + // TODO HF: fix for trees without segregation flag + // NOTE: constants count is serialized erroneously in the following 2 cases + (Coll(t1.bytes:_*), 0) -> success(Helpers.decodeBytes("000008d3")), + (Helpers.decodeBytes("000008d3"), 0) -> success(Helpers.decodeBytes("00000008d3")), + // tree with segregation flag, empty constants array + (Coll(t2.bytes:_*), 0) -> success(Helpers.decodeBytes("100008d3")), + (Helpers.decodeBytes("100008d3"), 0) -> success(Helpers.decodeBytes("100008d3")), + // 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(t4.bytes:_*), 0) -> Failure(new AssertionError("assertion failed: expected new constant to have the same SInt$ tpe, got SSigmaProp")) + ) + }, existingFeature( { (x: (Coll[Byte], Int)) => SigmaDsl.substConstants(x._1, Coll[Int](x._2), Coll[Any](SigmaDsl.sigmaProp(false))(RType.AnyType))(RType.AnyType) diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala index c4bb10d41c..2d27ab1523 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala @@ -1,16 +1,33 @@ package special.sigma +import java.util + +import org.ergoplatform.{ErgoAddressEncoder, ErgoLikeTransaction, ErgoLikeContext, ErgoLikeInterpreter, Input, ErgoBox, DataInput, ErgoScriptPredef} import org.scalatest.prop.PropertyChecks import sigmastate.interpreter.Interpreter.ScriptEnv import org.scalacheck.{Arbitrary, Gen} import org.scalatest.{PropSpec, Matchers} import scala.util.{Success, Failure, Try} -import sigmastate.Values.SValue +import sigmastate.Values.{Constant, SValue, ConstantNode, ByteArrayConstant, IntConstant, ErgoTree} import scalan.RType -import org.ergoplatform.dsl.{SigmaContractSyntax, TestContractSpec} -import sigmastate.eval.{IRContext, SigmaDsl} -import sigmastate.helpers.SigmaPPrint +import scalan.util.Extensions._ +import org.ergoplatform.dsl.{SigmaContractSyntax, TestContractSpec, ContractSpec} +import org.ergoplatform.validation.{ValidationRules, SigmaValidationSettings} +import sigmastate.{eval, SSigmaProp, SType} +import SType.AnyOps +import org.ergoplatform.SigmaConstants.ScriptCostLimit +import sigmastate.basics.DLogProtocol.{ProveDlog, DLogProverInput} +import sigmastate.basics.{SigmaProtocol, SigmaProtocolPrivateInput, SigmaProtocolCommonInput} +import sigmastate.eval.{CompiletimeIRContext, Evaluation, CostingBox, SigmaDsl, IRContext, CostingDataContext} +import sigmastate.eval.Extensions._ +import sigmastate.utils.Helpers._ +import sigmastate.lang.Terms.ValueOps +import sigmastate.helpers.{ErgoLikeContextTesting, SigmaPPrint} +import sigmastate.helpers.TestingHelpers._ +import sigmastate.interpreter.{ProverResult, ContextExtension, ProverInterpreter} +import sigmastate.serialization.ValueSerializer +import sigmastate.utxo.{DeserializeContext, DeserializeRegister} import special.collection.Coll import scala.math.Ordering @@ -22,22 +39,22 @@ class SigmaDslTesting extends PropSpec with SigmaTestingData with SigmaContractSyntax with SigmaTypeGens { suite => - lazy val spec = TestContractSpec(suite)(new TestingIRContext) + lazy val spec: ContractSpec = TestContractSpec(suite)(new TestingIRContext) override def contractEnv: ScriptEnv = Map() - implicit def IR = new TestingIRContext { + def createIR(): IRContext = new TestingIRContext { override val okPrintEvaluatedEntries: Boolean = false override val okMeasureOperationTime: Boolean = true } - def checkEq[A,B](f: A => B)(g: A => B): A => Try[B] = { x: A => - val b1 = Try(f(x)); val b2 = Try(g(x)) + def checkEq[A,B](scalaFunc: A => B)(g: A => (B, Int)): A => Try[(B, Int)] = { x: A => + val b1 = Try(scalaFunc(x)); val b2 = Try(g(x)) (b1, b2) match { - case (res @ Success(b1), Success(b2)) => + case (Success(b1), res @ Success((b2, _))) => assert(b1 == b2) res - case (res @ Failure(t1), Failure(t2)) => + case (Failure(t1), res @ Failure(t2)) => val c1 = rootCause(t1).getClass val c2 = rootCause(t2).getClass c1 shouldBe c2 @@ -77,10 +94,25 @@ class SigmaDslTesting extends PropSpec indices <- Gen.containerOfN[Array, Int](nIndexes, Gen.choose(0, arrLength - 1)) } yield indices + class FeatureProvingInterpreter extends ErgoLikeInterpreter()(new CompiletimeIRContext) with ProverInterpreter { + override type CTX = ErgoLikeContext + + def decodeSecretInput(decimalStr: String): DLogProverInput = DLogProverInput(BigInt(decimalStr).bigInteger) - case class EqualityChecker[T: RType](obj: T) { - def apply[R: RType](dslFunc: T => R)(script: String) = - checkEq(func[T, R](script))(dslFunc)(obj) + val sk1: DLogProverInput = decodeSecretInput("416167686186183758173232992934554728075978573242452195968805863126437865059") + val sk2: DLogProverInput = decodeSecretInput("34648336872573478681093104997365775365807654884817677358848426648354905397359") + val sk3: DLogProverInput = decodeSecretInput("50415569076448343263191022044468203756975150511337537963383000142821297891310") + + val secrets: Seq[SigmaProtocolPrivateInput[_ <: SigmaProtocol[_], _ <: SigmaProtocolCommonInput[_]]] = { + // Note, not all secrets are used, which is required by checkVerify + // This is to make AtLeast to be unproved and thus the verify is successfull + // because of the other condition in SigmaOr (see checkVerify) + val dlogs: IndexedSeq[DLogProverInput] = Vector(sk1) + dlogs + } + + val pubKeys: Seq[ProveDlog] = Vector(sk1, sk2, sk3) + .collect { case in: DLogProverInput => in.publicImage } } /** Type of the language feature to be tested. */ @@ -107,8 +139,6 @@ class SigmaDslTesting extends PropSpec printExpectedExpr: Boolean = true, logScript: Boolean = LogScriptDefault ) { - def printExpectedExprOff = copy(printExpectedExpr = false) - /** Called to print test case expression (when it is not given). * Can be used to create regression test cases. */ def printSuggestion(cf: CompiledFunc[_,_]): Unit = { @@ -136,7 +166,7 @@ class SigmaDslTesting extends PropSpec } /** v3 implementation*/ - private var _oldF: CompiledFunc[A, B] = null + private var _oldF: CompiledFunc[A, B] = _ def oldF: CompiledFunc[A, B] = { if (_oldF == null) { _oldF = oldImpl() @@ -146,7 +176,7 @@ class SigmaDslTesting extends PropSpec } /** v4 implementation*/ - private var _newF: CompiledFunc[A, B] = null + private var _newF: CompiledFunc[A, B] = _ def newF: CompiledFunc[A, B] = { if (_newF == null) { _newF = newImpl() @@ -159,7 +189,7 @@ class SigmaDslTesting extends PropSpec * semantic function (scalaFunc) on the given input. * @param input data which is used to execute feature * @return result of feature execution */ - def checkEquality(input: A, logInputOutput: Boolean = false): Try[B] = featureType match { + def checkEquality(input: A, logInputOutput: Boolean = false): Try[(B, Int)] = featureType match { case ExistingFeature => // check both implementations with Scala semantic val oldRes = checkEq(scalaFunc)(oldF)(input) @@ -188,24 +218,183 @@ class SigmaDslTesting extends PropSpec featureType match { case ExistingFeature => // check both implementations with Scala semantic - val oldRes = checkEq(scalaFunc)(oldF)(input) - oldRes.get shouldBe expectedResult + val (oldRes, _) = checkEq(scalaFunc)(oldF)(input).get + oldRes shouldBe expectedResult if (!(newImpl eq oldImpl)) { - val newRes = checkEq(scalaFunc)(newF)(input) - newRes.get shouldBe expectedResult + val (newRes, _) = checkEq(scalaFunc)(newF)(input).get + newRes shouldBe expectedResult } case AddedFeature => Try(oldF(input)).isFailure shouldBe true if (!(newImpl eq oldImpl)) { - val newRes = checkEq(scalaFunc)(newF)(input) - newRes.get shouldBe expectedResult + val (newRes, _) = checkEq(scalaFunc)(newF)(input).get + newRes shouldBe expectedResult } } } + /** Creates a new ErgoLikeContext using given [[CostingDataContext]] as template. + * Copies most of the data from ctx and the missing data is taken from the args. + * This is a helper method to be used in tests only. + */ + def createErgoLikeContext(ctx: CostingDataContext, + validationSettings: SigmaValidationSettings, + costLimit: Long, + initCost: Long + ): ErgoLikeContext = { + val treeData = SigmaDsl.toAvlTreeData(ctx.lastBlockUtxoRootHash) + val dataBoxes = ctx.dataInputs.toArray.map(SigmaDsl.toErgoBox) + val boxesToSpend = ctx.inputs.toArray.map(SigmaDsl.toErgoBox) + val txInputs = boxesToSpend.map(b => Input(b.id, ProverResult.empty)) + val txDataInputs = dataBoxes.map(b => DataInput(b.id)) + val txOutputCandidates = ctx.outputs.toArray.map(SigmaDsl.toErgoBox) + val tx = new ErgoLikeTransaction( + txInputs, txDataInputs, txOutputCandidates.toIndexedSeq) + val selfIndex = boxesToSpend.indexWhere(b => util.Arrays.equals(b.id, ctx.selfBox.id.toArray)) + + val extension = ContextExtension( + values = ctx.vars.toArray.zipWithIndex.collect { + case (v, i) if v != null => + val tpe = Evaluation.rtypeToSType(v.tVal) + i.toByte -> ConstantNode(v.value.asWrappedType, tpe) + }.toMap + ) + new ErgoLikeContext( + treeData, ctx.headers, ctx.preHeader, + dataBoxes, boxesToSpend, tx, selfIndex, + extension, validationSettings, costLimit, initCost) + } + + /** Executes the default feature verification wrapper script using: + * 1) the given input + * 2) the given expected intermediate result + * 3) the total expected execution cost of the verification + */ + def checkVerify(input: A, expectedRes: B, expectedCost: Int): Unit = { + val tpeA = Evaluation.rtypeToSType(oldF.tA) + val tpeB = Evaluation.rtypeToSType(oldF.tB) + + val prover = new FeatureProvingInterpreter() + + // Create synthetic ErgoTree which uses all main capabilities of evaluation machinery. + // 1) first-class functions (lambdas); 2) Context variables; 3) Registers; 4) Equality + // for all types; 5) Embedding of boolean to SigmaProp; 6) Sigma propositions (&&, ||, AtLeast) + // 7) Deserialization from SELF and Context + // Every language Feature is tested as part of this wrapper script. + // Inclusion of all the features influences the expected cost estimation values + val compiledTree = { + val code = + s"""{ + | val func = ${oldF.script} + | val res1 = func(getVar[${oldF.tA.name}](1).get) + | val res2 = SELF.R4[${oldF.tB.name}].get + | sigmaProp(res1 == res2) && pkAlice + |} + """.stripMargin + + val IR = new CompiletimeIRContext + val pkAlice = prover.pubKeys.head.toSigmaProp + val env = Map("pkAlice" -> pkAlice) + + // Compile script the same way it is performed by applications (i.e. via Ergo Appkit) + val prop = ErgoScriptPredef.compileWithCosting( + env, code, ErgoAddressEncoder.MainnetNetworkPrefix)(IR).asSigmaProp + + // Add additional oparations which are not yet implemented in ErgoScript compiler + val multisig = sigmastate.AtLeast( + IntConstant(2), + Seq( + pkAlice, + DeserializeRegister(ErgoBox.R5, SSigmaProp), // deserialize pkBob + DeserializeContext(2, SSigmaProp))) // deserialize pkCarol + ErgoTree.fromProposition(sigmastate.SigmaOr(prop, multisig)) + } + + val pkBobBytes = ValueSerializer.serialize(prover.pubKeys(1).toSigmaProp) + val pkCarolBytes = ValueSerializer.serialize(prover.pubKeys(2).toSigmaProp) + val newRegisters = Map( + ErgoBox.R4 -> Constant[SType](expectedRes.asInstanceOf[SType#WrappedType], tpeB), + ErgoBox.R5 -> ByteArrayConstant(pkBobBytes) + ) + + val ergoCtx = input match { + case ctx: CostingDataContext => + // the context is passed as function argument (see func in the script) + // Since Context is singleton, we should use this instance as the basis + // for execution of verify instead of a new dummy context. + val self = ctx.selfBox.asInstanceOf[CostingBox] + val newSelf = self.copy( + ebox = updatedRegisters(self.ebox, newRegisters) + ) + + // We add ctx as it's own variable with id = 1 + val ctxVar = eval.Extensions.toAnyValue[special.sigma.Context](ctx)(special.sigma.ContextRType) + val carolVar = eval.Extensions.toAnyValue[Coll[Byte]](pkCarolBytes.toColl)(RType[Coll[Byte]]) + val newCtx = ctx + .withUpdatedVars(1 -> ctxVar, 2 -> carolVar) + .copy( + selfBox = newSelf, + inputs = { + val selfIndex = ctx.inputs.indexWhere(b => b.id == ctx.selfBox.id, 0) + ctx.inputs.updated(selfIndex, newSelf) + }) + + createErgoLikeContext( + newCtx, + ValidationRules.currentSettings, + ScriptCostLimit.value, + initCost = 0L + ) + + case _ => + ErgoLikeContextTesting.dummy( + createBox(0, compiledTree, additionalRegisters = newRegisters) + ).withBindings( + 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA), + 2.toByte -> ByteArrayConstant(pkCarolBytes) + ).asInstanceOf[ErgoLikeContext] + } + + val pr = prover.prove(compiledTree, ergoCtx, fakeMessage).getOrThrow + + implicit val IR: IRContext = createIR() + + val verifier = new ErgoLikeInterpreter() { type CTX = ErgoLikeContext } + + val verificationCtx = ergoCtx.withExtension(pr.extension) + + val vres = verifier.verify(compiledTree, verificationCtx, pr, fakeMessage) + vres match { + case Success((ok, cost)) => + ok shouldBe true + val verificationCost = cost.toIntExact +// NOTE: you can uncomment this line and comment the assertion in order to +// simplify adding new test vectors for cost estimation +// if (expectedCost != verificationCost) { +// println(s"Script: $script") +// println(s"Cost: $verificationCost\n") +// } + assertResult(expectedCost, + s"Actual verify() cost $cost != expected $expectedCost")(verificationCost) + + case Failure(t) => throw t + } + } } + object FeatureTest { + /** Cost of the feature verify script. + * @see checkVerify() */ + val VerifyScriptCost = 6317 + } + + /** Represents expected result of successful feature test exectuion. + * @param value value returned by feature function (and the corresponding Scala function) + * @param cost expected cost value of the verification execution + * @see [[testCases]] + */ + case class Expected[+A](value: A, cost: Int) /** Describes existing language feature which should be equally supported in both v3 and * v4 of the language. @@ -241,8 +430,8 @@ class SigmaDslTesting extends PropSpec FeatureTest(AddedFeature, script, scalaFunc, Option(expectedExpr), oldImpl, newImpl) } - val contextGen: Gen[Context] = ergoLikeContextGen.map(c => c.toSigmaContext(IR, false)) - implicit val arbContext = Arbitrary(contextGen) + val contextGen: Gen[Context] = ergoLikeContextGen.map(c => c.toSigmaContext(createIR(), isCost = false)) + implicit val arbContext: Arbitrary[Context] = Arbitrary(contextGen) /** NOTE, this should be `def` to allow overriding of generatorDrivenConfig in derived Spec classes. */ def DefaultMinSuccessful: MinSuccessful = MinSuccessful(generatorDrivenConfig.minSuccessful) @@ -250,8 +439,25 @@ class SigmaDslTesting extends PropSpec val PrintTestCasesDefault: Boolean = false val FailOnTestVectorsDefault: Boolean = true + private def checkResult[B](res: Try[B], expectedRes: Try[B], failOnTestVectors: Boolean): Unit = { + (res, expectedRes) match { + case (Failure(exception), Failure(expectedException)) => + rootCause(exception).getClass shouldBe expectedException.getClass + case _ => + if (failOnTestVectors) { + assertResult(expectedRes, s"Actual: ${SigmaPPrint(res, height = 150).plainText}")(res) + } + else { + if (expectedRes != res) { + print("\nSuggested Expected Result: ") + SigmaPPrint.pprintln(res, height = 150) + } + } + } + } + /** Test the given test cases with expected results (aka test vectors). - * NOTE, is some cases (such as Context, Box, etc) sample generation is time consuming, so it + * NOTE, in some cases (such as Context, Box, etc) sample generation is time consuming, so it * makes sense to factor it out. * @param preGeneratedSamples optional pre-generated samples to reduce execution time */ @@ -264,32 +470,58 @@ class SigmaDslTesting extends PropSpec val table = Table(("x", "y"), cases:_*) forAll(table) { (x: A, expectedRes: Try[B]) => - val res = f.checkEquality(x, printTestCases) + val res = f.checkEquality(x, printTestCases).map(_._1) // TODO HF: remove this `if` once newImpl is implemented - if (f.featureType == ExistingFeature) { - (res, expectedRes) match { - case (Failure(exception), Failure(expectedException)) => - exception.getClass shouldBe expectedException.getClass - case _ => - if (failOnTestVectors) { - assertResult(expectedRes, s"Actual: ${SigmaPPrint(res, height = 150).plainText}")(res) - } - else { - if (expectedRes != res) { - print("\nSuggested Expected Result: ") - SigmaPPrint.pprintln(res, height = 150) - } - } - } + f.featureType match { + case ExistingFeature => + checkResult(res, expectedRes, failOnTestVectors) + case AddedFeature => + res.isFailure shouldBe true + Try(f.scalaFunc(x)) shouldBe expectedRes } } - preGeneratedSamples match { - case Some(samples) => - test(samples, f, printTestCases) - case None => - test(f, printTestCases) + test(preGeneratedSamples, f, printTestCases) + } + + /** Test the given test cases with expected results AND costs (aka test vectors). + * For all Success cases `f.checkVerify` is executed to exercise the whole + * `Interpreter.verify` execution and assert the expected cost. + * + * NOTE, in some cases (such as Context, Box, etc) sample generation is time consuming, so it + * makes sense to factor it out. + * + * @param preGeneratedSamples optional pre-generated samples to reduce execution time + * if None, then the given Arbitrary is used to generate samples + */ + def verifyCases[A: Ordering : Arbitrary : ClassTag, B] + (cases: Seq[(A, Try[Expected[B]])], + f: FeatureTest[A, B], + printTestCases: Boolean = PrintTestCasesDefault, + failOnTestVectors: Boolean = FailOnTestVectorsDefault, + preGeneratedSamples: Option[Seq[A]] = None): Unit = { + + val table = Table(("x", "y"), cases:_*) + forAll(table) { (x: A, expectedRes: Try[Expected[B]]) => + val funcRes = f.checkEquality(x, printTestCases) + + val expectedResValue = expectedRes.map(_.value) + // TODO HF: remove this `match` once newImpl is implemented + f.featureType match { + case ExistingFeature => + checkResult(funcRes.map(_._1), expectedResValue, failOnTestVectors) + + (funcRes, expectedRes) match { + case (Success((y, _)), Success(Expected(_, expectedCost))) => + f.checkVerify(x, y, expectedCost) + case _ => + } + case AddedFeature => + funcRes.isFailure shouldBe true + Try(f.scalaFunc(x)) shouldBe expectedResValue + } } + test(preGeneratedSamples, f, printTestCases) } /** Generate samples in sorted order. @@ -298,7 +530,7 @@ class SigmaDslTesting extends PropSpec * @return array-backed ordered sequence of samples */ def genSamples[A: Ordering: ClassTag](gen: Gen[A], config: PropertyCheckConfigParam): Seq[A] = { - implicit val arb = Arbitrary(gen) + implicit val arb: Arbitrary[A] = Arbitrary(gen) genSamples[A](config) } @@ -308,123 +540,133 @@ class SigmaDslTesting extends PropSpec */ def genSamples[A: Arbitrary: Ordering: ClassTag](config: PropertyCheckConfigParam): Seq[A] = { val inputs = scala.collection.mutable.ArrayBuilder.make[A]() - forAll(config) { (x: A) => + forAll(config) { x: A => inputs += x } inputs.result().sorted } - def test[A: Ordering : ClassTag, B] - (samples: Seq[A], + /** Test the given samples or generate new samples using the given Arbitrary. + * For each sample `f.checkEquality` is executed. + */ + def test[A: Arbitrary: Ordering : ClassTag, B] + (preGeneratedSamples: Option[Seq[A]], f: FeatureTest[A, B], printTestCases: Boolean): Unit = { + // either get provides or generate new samples (in sorted order) + val samples = preGeneratedSamples.getOrElse(genSamples[A](DefaultMinSuccessful)) - // then tests them in the sorted order, this will output a nice log of test cases + // then tests them, this will output a nice log of test cases (provided printTestCases == true) samples.foreach { x => f.checkEquality(x, printTestCases) } } - def test[A: Ordering : ClassTag, B](samples: Seq[A], f: FeatureTest[A, B]): Unit = { - test(samples, f, PrintTestCasesDefault) + def test[A: Arbitrary : Ordering : ClassTag, B](samples: Seq[A], f: FeatureTest[A, B]): Unit = { + test(Some(samples), f, PrintTestCasesDefault) } def test[A: Arbitrary : Ordering : ClassTag, B] (f: FeatureTest[A, B], printTestCases: Boolean = PrintTestCasesDefault): Unit = { - // first generate all test inputs - val samples = genSamples[A](DefaultMinSuccessful) - // then test them - test(samples, f, printTestCases) + test(None, f, printTestCases) } + /** Helper implementation for ordering samples. */ trait GroupElementOrdering extends Ordering[GroupElement] { /** Compares `x: ECPoint` string representation with `y: ECPoint` string for order. - * @returns a negative integer, zero, or a positive integer as the + * @return a negative integer, zero, or a positive integer as the * `x` is less than, equal to, or greater than `y`. */ - def compare(x: GroupElement, y: GroupElement) = { + def compare(x: GroupElement, y: GroupElement): Int = { SigmaDsl.toECPoint(x).toString.compareTo(SigmaDsl.toECPoint(y).toString) } } implicit object GroupElementOrdering extends GroupElementOrdering + /** Helper implementation for ordering samples. */ trait AvlTreeOrdering extends Ordering[AvlTree] { /** Compares this `x: AvlTree` string representation with `y: AvlTree` string for order. - * @returns a negative integer, zero, or a positive integer as the + * @return a negative integer, zero, or a positive integer as the * `x` is less than, equal to, or greater than `y`. */ - def compare(x: AvlTree, y: AvlTree) = { + def compare(x: AvlTree, y: AvlTree): Int = { x.toString.compareTo(y.toString) } } implicit object AvlTreeOrdering extends AvlTreeOrdering + /** Helper implementation for ordering samples. */ class CollOrdering[T: Ordering] extends Ordering[Coll[T]] { - implicit val O = implicitly[Ordering[Iterable[T]]] + val O = Ordering[Iterable[T]] /** Compares this `x: Coll` with `y: Coll` using Ordering for underlying Array. - * @returns a negative integer, zero, or a positive integer as the + * @return a negative integer, zero, or a positive integer as the * `x` is less than, equal to, or greater than `y`. */ - def compare(x: Coll[T], y: Coll[T]) = { + def compare(x: Coll[T], y: Coll[T]): Int = { O.compare(x.toArray, y.toArray) } } implicit def collOrdering[T: Ordering]: Ordering[Coll[T]] = new CollOrdering[T] + /** Helper implementation for ordering samples. */ trait BoxOrdering extends Ordering[Box] { /** Compares this `x: Box` string representation with `y: Box` string for order. - * @returns a negative integer, zero, or a positive integer as the + * @return a negative integer, zero, or a positive integer as the * `x` is less than, equal to, or greater than `y`. */ - def compare(x: Box, y: Box) = { + def compare(x: Box, y: Box): Int = { x.toString.compareTo(y.toString) } } implicit object BoxOrdering extends BoxOrdering + /** Helper implementation for ordering samples. */ trait PreHeaderOrdering extends Ordering[PreHeader] { /** Compares this `x: PreHeader` with `y: PreHeader` using block height. - * @returns a negative integer, zero, or a positive integer as the + * @return a negative integer, zero, or a positive integer as the * `x` is less than, equal to, or greater than `y`. */ - def compare(x: PreHeader, y: PreHeader) = { + def compare(x: PreHeader, y: PreHeader): Int = { Ordering.Int.compare(x.height, y.height) } } implicit object PreHeaderOrdering extends PreHeaderOrdering + /** Helper implementation for ordering samples. */ trait HeaderOrdering extends Ordering[Header] { /** Compares this `x: Header` with `y: Header` using block height. - * @returns a negative integer, zero, or a positive integer as the + * @return a negative integer, zero, or a positive integer as the * `x` is less than, equal to, or greater than `y`. */ - def compare(x: Header, y: Header) = { + def compare(x: Header, y: Header): Int = { Ordering.Int.compare(x.height, y.height) } } implicit object HeaderOrdering extends HeaderOrdering + /** Helper implementation for ordering samples. */ trait ContextOrdering extends Ordering[Context] { - val O = Ordering[(Int, Coll[Byte])] + val O: Ordering[(Int, Coll[Byte])] = Ordering[(Int, Coll[Byte])] /** Compares this `x: Context` with `y: Context` using block height and SELF.id. - * @returns a negative integer, zero, or a positive integer as the + * @return a negative integer, zero, or a positive integer as the * `x` is less than, equal to, or greater than `y`. */ - def compare(x: Context, y: Context) = { + def compare(x: Context, y: Context): Int = { O.compare((x.HEIGHT, x.SELF.id), (y.HEIGHT, y.SELF.id)) } } implicit object ContextOrdering extends ContextOrdering + /** Helper implementation for ordering samples. */ trait SigmaPropOrdering extends Ordering[SigmaProp] { /** Compares this `x: SigmaProp` with `y: SigmaProp` using string representation. - * @returns a negative integer, zero, or a positive integer as the + * @return a negative integer, zero, or a positive integer as the * `x` is less than, equal to, or greater than `y`. */ - def compare(x: SigmaProp, y: SigmaProp) = { + def compare(x: SigmaProp, y: SigmaProp): Int = { x.toString.compareTo(y.toString) } } diff --git a/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala b/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala index da555c8165..cd0be01249 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala @@ -8,6 +8,7 @@ import sigmastate.{AvlTreeFlags, TrivialProp} import sigmastate.Values.{BooleanConstant, IntConstant} import org.scalacheck.{Arbitrary, Gen} import sigmastate.helpers.SigmaTestingCommons +import sigmastate.helpers.TestingHelpers._ import sigmastate.eval._ import sigmastate.eval.Extensions._ import org.ergoplatform.{ErgoLikeContext, DataInput, ErgoLikeTransaction, ErgoBox}