From bf0f4bcfd9b0d675f56e38abe0fdf4954fec3f99 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 6 Jul 2020 20:46:35 +0300 Subject: [PATCH 01/31] ContextExtension serialization --- .../org/ergoplatform/ErgoLikeTransaction.scala | 8 ++++++++ .../interpreter/InterpreterContext.scala | 2 +- .../ergoplatform/ErgoLikeTransactionSpec.scala | 17 ++++++++++++++--- .../generators/ObjectGenerators.scala | 2 +- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index c5d850d457..f05c6e5a15 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -105,6 +105,14 @@ class ErgoLikeTransaction(override val inputs: IndexedSeq[Input], } override def hashCode(): Int = id.hashCode() + + /** Similar to case class `copy` method. Different name is used to not interfere with + * possible derived case classes. + */ + def clone(inputs: IndexedSeq[Input] = inputs, + dataInputs: IndexedSeq[DataInput] = dataInputs, + outputCandidates: IndexedSeq[ErgoBoxCandidate] = outputCandidates) = + new ErgoLikeTransaction(inputs, dataInputs, outputCandidates) } object ErgoLikeTransactionSerializer extends SigmaSerializer[ErgoLikeTransaction, ErgoLikeTransaction] { diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index ea2470c0e7..898e2671d1 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -30,7 +30,7 @@ object ContextExtension { } override def parse(r: SigmaByteReader): ContextExtension = { - val extSize = r.getByte() + val extSize = r.getUByte() val ext = (0 until extSize) .map(_ => (r.getByte(), r.getValue().asInstanceOf[EvaluatedValue[_ <: SType]])) .toMap[Byte, EvaluatedValue[_ <: SType]] diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala index 79036122d0..eafad6f981 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala @@ -2,11 +2,11 @@ package org.ergoplatform import org.ergoplatform.ErgoBox.TokenId import org.scalatest.prop.GeneratorDrivenPropertyChecks -import org.scalatest.{Matchers, PropSpec} +import org.scalatest.{PropSpec, Matchers} import scorex.util.Random -import sigmastate.Values.ByteArrayConstant +import sigmastate.Values.{ByteArrayConstant, IntConstant} import sigmastate.helpers.SigmaTestingCommons -import sigmastate.interpreter.{ContextExtension, ProverResult} +import sigmastate.interpreter.{ProverResult, ContextExtension} import sigmastate.serialization.SigmaSerializer import sigmastate.serialization.generators.ObjectGenerators import sigmastate.eval._ @@ -161,4 +161,15 @@ class ErgoLikeTransactionSpec extends PropSpec } } + property("context extension serialization") { + forAll { tx: ErgoLikeTransaction => + val ce = ContextExtension((Byte.MinValue to (Byte.MaxValue - 1)).map(i => i.toByte -> IntConstant(4)).toMap) + val wrongInput = Input(tx.inputs.head.boxId, ProverResult(Array.emptyByteArray, ce)) + val ins = IndexedSeq(wrongInput) ++ tx.inputs.tail + val tx2 = tx.clone(inputs = ins) + val bs = ErgoLikeTransactionSerializer.toBytes(tx2) + val restored = ErgoLikeTransactionSerializer.fromBytes(bs) + restored.inputs.head.extension.values.size shouldBe tx2.inputs.head.extension.values.size + } + } } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 6407db9f64..048cf7327d 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -198,7 +198,7 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with val unsignedShortGen: Gen[Short] = Gen.chooseNum(0, Short.MaxValue).map(_.toShort) val contextExtensionGen: Gen[ContextExtension] = for { - values <- Gen.sequence(contextExtensionValuesGen(0, 3)) + values <- Gen.sequence(contextExtensionValuesGen(0, 5)) } yield ContextExtension(values.asScala.toMap) val serializedProverResultGen: Gen[ProverResult] = for { From ca6c6dc42c1994d6bc35282dd82aaa6141b3fb75 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 26 Oct 2020 20:08:54 +0300 Subject: [PATCH 02/31] towards-v4.0: activatedScriptVersion + ScalaDocs --- .../org/ergoplatform/ErgoLikeContext.scala | 29 ++--- .../sigmastate/interpreter/Interpreter.scala | 10 ++ .../interpreter/InterpreterContext.scala | 33 +++++- .../ScriptVersionSwitchSpecification.scala | 100 ++++++++++++++++++ 4 files changed, 157 insertions(+), 15 deletions(-) create mode 100644 sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 6f5544e847..89a8ccb0ed 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -19,18 +19,20 @@ import spire.syntax.all.cfor /** * TODO lastBlockUtxoRoot should be calculated from headers if it is nonEmpty * - * @param selfIndex - index of the box in `boxesToSpend` that contains the script we're evaluating - * @param lastBlockUtxoRoot - state root before current block application - * @param headers - fixed number of last block headers in descending order (first header is the newest one) - * @param preHeader - fields of block header with the current `spendingTransaction`, that can be predicted - * by a miner before it's formation - * @param dataBoxes - boxes, that corresponds to id's of `spendingTransaction.dataInputs` - * @param boxesToSpend - boxes, that corresponds to id's of `spendingTransaction.inputs` - * @param spendingTransaction - transaction that contains `self` box - * @param extension - prover-defined key-value pairs, that may be used inside a script - * @param validationSettings validataion parameters passed to Interpreter.verify to detect soft-fork conditions - * @param costLimit hard limit on accumulated execution cost, if exceeded lead to CostLimitException to be thrown - * @param initCost initial value of execution cost already accumulated before Interpreter.verify is called + * @param selfIndex - index of the box in `boxesToSpend` that contains the script we're evaluating + * @param lastBlockUtxoRoot - state root before current block application + * @param headers - fixed number of last block headers in descending order (first header is the newest one) + * @param preHeader - fields of block header with the current `spendingTransaction`, that can be predicted + * by a miner before it's formation + * @param dataBoxes - boxes, that corresponds to id's of `spendingTransaction.dataInputs` + * @param boxesToSpend - boxes, that corresponds to id's of `spendingTransaction.inputs` + * @param spendingTransaction - transaction that contains `self` box + * @param extension - prover-defined key-value pairs, that may be used inside a script + * @param validationSettings validataion parameters passed to Interpreter.verify to detect soft-fork conditions + * @param costLimit hard limit on accumulated execution cost, if exceeded lead to CostLimitException to be thrown + * @param initCost initial value of execution cost already accumulated before Interpreter.verify is called + * @param activatedScriptVersion Maximum version of ErgoTree currently activated on the + * network. The activation is performed via miners voting. */ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val headers: Coll[Header], @@ -42,7 +44,8 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val extension: ContextExtension, val validationSettings: SigmaValidationSettings, val costLimit: Long, - val initCost: Long + val initCost: Long, + val activatedScriptVersion: Byte = 0 ) extends InterpreterContext { /* NOHF PROOF: diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index fe1ab9141d..f3f8bfbd7f 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -195,6 +195,8 @@ trait Interpreter extends ScorexLogging { def fullReduction(ergoTree: ErgoTree, context: CTX, env: ScriptEnv): (SigmaBoolean, Long) = { + if (context.activatedScriptVersion > Interpreter.MaxSupportedScriptVersion) { + } implicit val vs: SigmaValidationSettings = context.validationSettings val initCost = JMath.addExact(ergoTree.complexity.toLong, context.initCost) @@ -346,6 +348,14 @@ object Interpreter { val emptyEnv: ScriptEnv = Map.empty[String, Any] val ScriptNameProp = "ScriptName" + /** Maximum version of ErgoTree supported by this interpreter release. + * See version bits in `ErgoTree.header` for more details. + * This value should be increased with each new language update via soft-fork. + * For example in version 3.x-4.x this value should be 0, in 5.x increased to 1, + * in 6.x set to 2, etc. + */ + val MaxSupportedScriptVersion: Int = 0 + def error(msg: String) = throw new InterpreterException(msg) } diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index ebe83519b0..e4905c9fe7 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -10,9 +10,15 @@ import special.sigma import special.sigma.AnyValue /** - * User-defined variables to be put into context + * User-defined variables to be put into context. + * Each variable is identified by `id: Byte` and can be accessed from a script + * using `getVar[T](id)` operation. + * The value of the variable is represented by [[sigmastate.Values.Constant]] instance, + * which contains both data value and [[SType]] descriptor. The descriptor is checked + * against the type `T` expected in the script operation. If the types don't match, + * exception is thrown and the box spending (protected by the script) fails. * - * @param values - key-value pairs + * @param values internal container of the key-value pairs */ case class ContextExtension(values: Map[Byte, EvaluatedValue[_ <: SType]]) { def add(bindings: (Byte, EvaluatedValue[_ <: SType])*): ContextExtension = @@ -40,12 +46,35 @@ object ContextExtension { } +/** Base class of the context passed to verifier and prover. + * @see [[sigmastate.interpreter.Interpreter]] + */ trait InterpreterContext { + /** Prover-defined key-value pairs, that may be used inside a script. */ val extension: ContextExtension + + /** Validataion parameters passed to Interpreter.verify to detect soft-fork conditions. */ val validationSettings: SigmaValidationSettings + + /** Hard limit on accumulated execution cost. Exceeding it leads to CostLimitException + * to be thrown. + */ val costLimit: Long + + /** Initial value of execution cost already accumulated before `Interpreter.verify`(or + * `prove`) is called. + */ val initCost: Long + /** Maximum version of ErgoTree currently activated on the network. The activation is + * performed via miners voting. + * The maximum version supported by the interpreter is defined by + * `Interpreter.MaxSupportedScriptVersion`. As a result, the execution of the + * `Interpreter.verify` and `Interpreter.prove` methods depend on the relation between + * max supported and activated version. (see docs/aot-jit-switch.md). + */ + def activatedScriptVersion: Byte + /** Creates a new instance with costLimit updated with given value. */ def withCostLimit(newCostLimit: Long): InterpreterContext diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala new file mode 100644 index 0000000000..aaf0822670 --- /dev/null +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -0,0 +1,100 @@ +package sigmastate + +import org.ergoplatform._ +import scorex.util.ModifierId +import sigmastate.Values._ +import sigmastate.basics.ProveDHTuple +import sigmastate.eval._ +import sigmastate.utxo._ +import special.collection._ +import sigmastate.utils.Helpers +import special.sigma.{SigmaDslTesting, Box} + +import scala.util.Success + +/** Specification to verify that the interpreter behaves according to docs/aot-jit-switch.md. */ +class ScriptVersionSwitchSpecification extends SigmaDslTesting { + override implicit val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 30) + implicit def IR = createIR() + + /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action + * -----|----------|-----------|----------------|---------|-------- + * 1 | inactive | candidate | Script v1 | v4.0 | R4.0-AOT-cost, R4.0-AOT-verify + */ + property("Rule 1 | inactive SF | candidate block | Script v1") { + val samples = genSamples[Coll[Box]](collOfN[Box](5), MinSuccessful(20)) + val b1 = CostingBox( + false, + new ErgoBox( + 1L, + new ErgoTree( + 0.toByte, + Vector(), + Right( + SigmaPropConstant( + CSigmaProp( + ProveDHTuple( + Helpers.decodeECPoint("02c1a9311ecf1e76c787ba4b1c0e10157b4f6d1e4db3ef0d84f411c99f2d4d2c5b"), + Helpers.decodeECPoint("027d1bd9a437e73726ceddecc162e5c85f79aee4798505bc826b8ad1813148e419"), + Helpers.decodeECPoint("0257cff6d06fe15d1004596eeb97a7f67755188501e36adc49bd807fe65e9d8281"), + Helpers.decodeECPoint("033c6021cff6ba5fdfc4f1742486030d2ebbffd9c9c09e488792f3102b2dcdabd5") + ) + ) + ) + ) + ), + Coll(), + Map( + ErgoBox.R4 -> ByteArrayConstant( + Helpers.decodeBytes( + "7200004cccdac3008001bc80ffc7ff9633bca3e501801380ff007900019d7f0001a8c9dfff5600d964011617ca00583f989c7f80007fee7f99b07f7f870067dc315180828080307fbdf400" + ) + ), + ErgoBox.R7 -> LongConstant(0L), + ErgoBox.R6 -> FalseLeaf, + ErgoBox.R5 -> ByteArrayConstant(Helpers.decodeBytes("7f")) + ), + ModifierId @@ ("7dffff48ab0000c101a2eac9ff17017f6180aa7fc6f2178000800179499380a5"), + 21591.toShort, + 638768 + ) + ) + val b2 = CostingBox( + false, + new ErgoBox( + 1000000000L, + new ErgoTree( + 0.toByte, + Vector(), + Right(BoolToSigmaProp(OR(ConcreteCollection(Array(FalseLeaf, AND(ConcreteCollection(Array(FalseLeaf, FalseLeaf), SBoolean))), SBoolean)))) + ), + Coll(), + Map(), + ModifierId @@ ("008677ffff7ff36dff00f68031140400007689ff014c9201ce8000a9ffe6ceff"), + 32767.toShort, + 32827 + ) + ) + + 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( + Vector((1, SCollectionType(SBox))), + Filter( + ValUse(1, SCollectionType(SBox)), + FuncValue(Vector((3, SBox)), GT(ExtractAmount(ValUse(3, SBox)), LongConstant(1L))) + ) + )), + preGeneratedSamples = Some(samples)) + + } +} From 40bc4f6ee86924b7a68ba489b605e55b2ec6730c Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 27 Oct 2020 21:23:42 +0300 Subject: [PATCH 03/31] towards-v4.0: Rule 3 test --- .../src/main/scala/sigmastate/Values.scala | 11 ++ .../sigmastate/interpreter/Interpreter.scala | 4 + .../ScriptVersionSwitchSpecification.scala | 145 +++++++++++------- .../sigmastate/helpers/NegativeTesting.scala | 2 +- .../sigmastate/helpers/TestingHelpers.scala | 5 +- 5 files changed, 109 insertions(+), 58 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index 09a5974289..d14045a758 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -1043,10 +1043,21 @@ object Values { /** Default header with constant segregation enabled. */ val ConstantSegregationHeader: Byte = (DefaultHeader | ConstantSegregationFlag).toByte + /** @return true if the constant segregation flag is set to 1 in the given header byte. */ @inline final def isConstantSegregation(header: Byte): Boolean = (header & ConstantSegregationFlag) != 0 + + /** @return true if the size flag is set to 1 in the given header byte. */ @inline final def hasSize(header: Byte): Boolean = (header & SizeFlag) != 0 + + /** @return a value of the version bits from the given header byte. */ @inline final def getVersion(header: Byte): Byte = (header & VersionMask).toByte + /** Update the version bits of the given header byte with the given version value. */ + @inline final def updateVersionBits(header: Byte, version: Byte): Byte = { + require(version < 8, s"ErgoTree.version should be < 8: $version") + (header | version).toByte + } + def substConstants(root: SValue, constants: IndexedSeq[Constant[SType]]): SValue = { val store = new ConstantStore(constants) val substRule = strategy[Any] { diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index f3f8bfbd7f..8745debbd8 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -196,6 +196,10 @@ trait Interpreter extends ScorexLogging { context: CTX, env: ScriptEnv): (SigmaBoolean, Long) = { if (context.activatedScriptVersion > Interpreter.MaxSupportedScriptVersion) { + + } else { + if (ergoTree.version > context.activatedScriptVersion) + throw new InterpreterException(s"Not supported script version ${ergoTree.version}") } implicit val vs: SigmaValidationSettings = context.validationSettings diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index aaf0822670..093790eae2 100644 --- a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -1,14 +1,20 @@ package sigmastate +import org.ergoplatform.ErgoBox.AdditionalRegisters import org.ergoplatform._ import scorex.util.ModifierId +import sigmastate.Values.ErgoTree.{DefaultHeader, updateVersionBits, SizeFlag} import sigmastate.Values._ -import sigmastate.basics.ProveDHTuple import sigmastate.eval._ +import sigmastate.helpers.ErgoLikeContextTesting +import sigmastate.helpers.TestingHelpers.createBox +import sigmastate.interpreter.Interpreter +import sigmastate.lang.exceptions.InterpreterException import sigmastate.utxo._ +import sigmastate.utils.Helpers._ import special.collection._ -import sigmastate.utils.Helpers import special.sigma.{SigmaDslTesting, Box} +import sigmastate.helpers.TestingHelpers._ import scala.util.Success @@ -17,64 +23,29 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { override implicit val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 30) implicit def IR = createIR() + val b1 = CostingBox( + false, + new ErgoBox( + 1L, + new ErgoTree( + 0.toByte, + Vector(), + Right(BoolToSigmaProp(OR(ConcreteCollection(Array(FalseLeaf, AND(ConcreteCollection(Array(FalseLeaf, FalseLeaf), SBoolean))), SBoolean)))) + ), + Coll(), + Map(), + ModifierId @@ ("008677ffff7ff36dff00f68031140400007689ff014c9201ce8000a9ffe6ceff"), + 32767.toShort, + 32827 + ) + ) + /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action * -----|----------|-----------|----------------|---------|-------- * 1 | inactive | candidate | Script v1 | v4.0 | R4.0-AOT-cost, R4.0-AOT-verify */ property("Rule 1 | inactive SF | candidate block | Script v1") { val samples = genSamples[Coll[Box]](collOfN[Box](5), MinSuccessful(20)) - val b1 = CostingBox( - false, - new ErgoBox( - 1L, - new ErgoTree( - 0.toByte, - Vector(), - Right( - SigmaPropConstant( - CSigmaProp( - ProveDHTuple( - Helpers.decodeECPoint("02c1a9311ecf1e76c787ba4b1c0e10157b4f6d1e4db3ef0d84f411c99f2d4d2c5b"), - Helpers.decodeECPoint("027d1bd9a437e73726ceddecc162e5c85f79aee4798505bc826b8ad1813148e419"), - Helpers.decodeECPoint("0257cff6d06fe15d1004596eeb97a7f67755188501e36adc49bd807fe65e9d8281"), - Helpers.decodeECPoint("033c6021cff6ba5fdfc4f1742486030d2ebbffd9c9c09e488792f3102b2dcdabd5") - ) - ) - ) - ) - ), - Coll(), - Map( - ErgoBox.R4 -> ByteArrayConstant( - Helpers.decodeBytes( - "7200004cccdac3008001bc80ffc7ff9633bca3e501801380ff007900019d7f0001a8c9dfff5600d964011617ca00583f989c7f80007fee7f99b07f7f870067dc315180828080307fbdf400" - ) - ), - ErgoBox.R7 -> LongConstant(0L), - ErgoBox.R6 -> FalseLeaf, - ErgoBox.R5 -> ByteArrayConstant(Helpers.decodeBytes("7f")) - ), - ModifierId @@ ("7dffff48ab0000c101a2eac9ff17017f6180aa7fc6f2178000800179499380a5"), - 21591.toShort, - 638768 - ) - ) - val b2 = CostingBox( - false, - new ErgoBox( - 1000000000L, - new ErgoTree( - 0.toByte, - Vector(), - Right(BoolToSigmaProp(OR(ConcreteCollection(Array(FalseLeaf, AND(ConcreteCollection(Array(FalseLeaf, FalseLeaf), SBoolean))), SBoolean)))) - ), - Coll(), - Map(), - ModifierId @@ ("008677ffff7ff36dff00f68031140400007689ff014c9201ce8000a9ffe6ceff"), - 32767.toShort, - 32827 - ) - ) verifyCases( { @@ -82,7 +53,6 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { 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 }) }, @@ -97,4 +67,69 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { preGeneratedSamples = Some(samples)) } + + def createErgoTree(headerFlags: Byte)(implicit IR: IRContext): ErgoTree = { + import ErgoTree._ + val code = + s"""{ + | val func = { (x: Coll[Box]) => x.filter({(b: Box) => b.value > 1 }) } + | val v = func(getVar[Coll[Box]](1).get) + | val r = SELF.R4[Coll[Box]].get + | sigmaProp(v == r) + |} + """.stripMargin + val env = Interpreter.emptyEnv + + // The following ops are performed by frontend: typecheck, create graphs, compile to Tree + val compiledTree = { + val internalProp = compiler.typecheck(env, code) + val costingRes = getCostingResult(env, internalProp)(IR) + val calcF = costingRes.calcF + val tree = IR.buildTree(calcF) + tree + } + ErgoTree.withSegregation(headerFlags, compiledTree) + } + + def testProve(ergoTree: ErgoTree, activatedScriptVersion: Byte) = { + val tpeA = SCollection(SBox) + val input = Coll[Box](b1) + val newRegisters: AdditionalRegisters = Map( + ErgoBox.R4 -> Constant[SType](Coll[Box]().asInstanceOf[SType#WrappedType], tpeA) + ) + + val ctx = copyContext(ErgoLikeContextTesting.dummy( + createBox(0, ergoTree, additionalRegisters = newRegisters) + ).withBindings( + 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA), + ).asInstanceOf[ErgoLikeContext])(activatedScriptVersion = activatedScriptVersion) + val prover = new FeatureProvingInterpreter() + val pr = prover.prove(ergoTree, ctx, fakeMessage).getOrThrow + pr + } + + /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action + * -----|----------|-----------|----------------|---------|-------- + * 3 | inactive | candidate | Script v2 | v4.0 | skip-pool-tx (cannot handle) + */ + property("Rule 3 | inactive SF | candidate block | Script v2") { + + assertExceptionThrown( + createErgoTree(headerFlags = updateVersionBits(DefaultHeader, 1)), + { t => + t.isInstanceOf[IllegalArgumentException] && + t.getMessage.contains("For newer version the size bit is required") + }) + + val headerFlags = ErgoTree.SizeFlag | updateVersionBits(DefaultHeader, 1 /* Script v2 */) + val ergoTree = createErgoTree(headerFlags = headerFlags.toByte) + + assertExceptionThrown( + testProve(ergoTree, activatedScriptVersion = 0 /* SF Status: inactive */), + { t => + t.isInstanceOf[InterpreterException] && + t.getMessage.contains(s"Not supported script version ${ergoTree.version}") + }) + } + } diff --git a/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala index 82f1a11f10..3fc245b684 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/NegativeTesting.scala @@ -14,7 +14,7 @@ trait NegativeTesting extends Matchers { def assertExceptionThrown(fun: => Any, assertion: Throwable => Boolean, clue: => String = ""): Unit = { try { fun - fail("exception is expected") + fail("exception is expected but hasn't been thrown") } catch { case e: Throwable => diff --git a/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala b/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala index bd520accd3..b8a51520ac 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala @@ -68,10 +68,11 @@ object TestingHelpers { extension: ContextExtension = ctx.extension, validationSettings: SigmaValidationSettings = ctx.validationSettings, costLimit: Long = ctx.costLimit, - initCost: Long = ctx.initCost): ErgoLikeContext = { + initCost: Long = ctx.initCost, + activatedScriptVersion: Byte = ctx.activatedScriptVersion): ErgoLikeContext = { new ErgoLikeContext( lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, - spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) + spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost, activatedScriptVersion) } /** Creates a new box by updating some of the additional registers with the given new bindings. From 199cd715beab9780a1e5dcdb13a2c0aac21f54a8 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 27 Oct 2020 23:54:20 +0300 Subject: [PATCH 04/31] towards-v4.0: fixes for Scala 2.11 --- .../scala/sigmastate/ScriptVersionSwitchSpecification.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index 093790eae2..f5bd55f008 100644 --- a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -52,7 +52,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { 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), success(Coll[Box](), 37397)) ) }, existingFeature({ (x: Coll[Box]) => x.filter({ (b: Box) => b.value > 1 }) }, @@ -101,7 +101,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { val ctx = copyContext(ErgoLikeContextTesting.dummy( createBox(0, ergoTree, additionalRegisters = newRegisters) ).withBindings( - 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA), + 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA) ).asInstanceOf[ErgoLikeContext])(activatedScriptVersion = activatedScriptVersion) val prover = new FeatureProvingInterpreter() val pr = prover.prove(ergoTree, ctx, fakeMessage).getOrThrow From ca72abba4d51622fdbcb00e01851834b9435e70d Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 28 Oct 2020 15:02:04 +0300 Subject: [PATCH 05/31] towards-v4.0: finished ScriptVersionSwitchSpecification for all rules --- .../org/ergoplatform/ErgoLikeContext.scala | 77 +++++--- .../sigmastate/interpreter/Interpreter.scala | 11 +- .../ScriptVersionSwitchSpecification.scala | 187 ++++++++++++++---- 3 files changed, 206 insertions(+), 69 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 89a8ccb0ed..1a6ba6746a 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -8,16 +8,16 @@ import sigmastate.Values._ import sigmastate._ import sigmastate.eval.Extensions._ import sigmastate.eval._ -import sigmastate.interpreter.{ContextExtension, InterpreterContext} +import sigmastate.interpreter.{ContextExtension, InterpreterContext, Interpreter} import sigmastate.serialization.OpCodes import sigmastate.serialization.OpCodes.OpCode import special.collection.Coll import special.sigma -import special.sigma.{AnyValue, Header, PreHeader} +import special.sigma.{AnyValue, PreHeader, Header} import spire.syntax.all.cfor -/** - * TODO lastBlockUtxoRoot should be calculated from headers if it is nonEmpty +/** Represents a script evaluation context to be passed to a prover and a verifier to execute and + * validate guarding proposition of input boxes of a transaction. * * @param selfIndex - index of the box in `boxesToSpend` that contains the script we're evaluating * @param lastBlockUtxoRoot - state root before current block application @@ -31,8 +31,17 @@ import spire.syntax.all.cfor * @param validationSettings validataion parameters passed to Interpreter.verify to detect soft-fork conditions * @param costLimit hard limit on accumulated execution cost, if exceeded lead to CostLimitException to be thrown * @param initCost initial value of execution cost already accumulated before Interpreter.verify is called - * @param activatedScriptVersion Maximum version of ErgoTree currently activated on the - * network. The activation is performed via miners voting. + * @param activatedScriptVersion Maximum version of ErgoTree currently activated on the network. + * The activation is performed via miners voting majority switches to higher version. + * For verification of *mined* blocks this parameter should be passed according + * to the latest voted (activated) script version on the network. + * However this is not the case for *candidate* blocks. + * When `activatedScriptVersion > Interpreter.MaxSupportedScriptVersion` + * then the interpreter accept script without verification which is not + * what should happen for *candidate* blocks. + * This means Ergo node should always pass Interpreter.MaxSupportedScriptVersion + * as a value of ErgoLikeContext.activatedScriptVersion during + * verification of candidate blocks (which is a default). */ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val headers: Coll[Header], @@ -45,8 +54,9 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val validationSettings: SigmaValidationSettings, val costLimit: Long, val initCost: Long, - val activatedScriptVersion: Byte = 0 + val activatedScriptVersion: Byte = Interpreter.MaxSupportedScriptVersion ) extends InterpreterContext { + // TODO lastBlockUtxoRoot should be calculated from headers if it is nonEmpty /* NOHF PROOF: Added: assert(preHeader != null) @@ -96,30 +106,19 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val self: ErgoBox = boxesToSpend(selfIndex) override def withCostLimit(newCostLimit: Long): ErgoLikeContext = - new ErgoLikeContext( - lastBlockUtxoRoot, headers, preHeader, - dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, newCostLimit, initCost) + ErgoLikeContext.copy(this)(costLimit = newCostLimit) override def withInitCost(newCost: Long): ErgoLikeContext = - new ErgoLikeContext( - lastBlockUtxoRoot, headers, preHeader, - dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, newCost) + ErgoLikeContext.copy(this)(initCost = newCost) override def withValidationSettings(newVs: SigmaValidationSettings): ErgoLikeContext = - new ErgoLikeContext( - lastBlockUtxoRoot, headers, preHeader, - dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, newVs, costLimit, initCost) + ErgoLikeContext.copy(this)(validationSettings = newVs) override def withExtension(newExtension: ContextExtension): ErgoLikeContext = - new ErgoLikeContext( - lastBlockUtxoRoot, headers, preHeader, - dataBoxes, boxesToSpend, spendingTransaction, selfIndex, newExtension, validationSettings, costLimit, initCost) + ErgoLikeContext.copy(this)(extension = newExtension) def withTransaction(newSpendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput]): ErgoLikeContext = - new ErgoLikeContext( - lastBlockUtxoRoot, headers, preHeader, - dataBoxes, boxesToSpend, newSpendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) - + ErgoLikeContext.copy(this)(spendingTransaction = newSpendingTransaction) override def toSigmaContext(isCost: Boolean, extensions: Map[Byte, AnyValue] = Map()): sigma.Context = { import Evaluation._ @@ -167,14 +166,18 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, extension == that.extension && validationSettings == that.validationSettings && costLimit == that.costLimit && - initCost == that.initCost + initCost == that.initCost && + activatedScriptVersion == that.activatedScriptVersion case _ => false } def canEqual(other: Any): Boolean = other.isInstanceOf[ErgoLikeContext] override def hashCode(): Int = { - val state = Array(lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) + val state = Array( + lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, spendingTransaction, + selfIndex, extension, validationSettings, costLimit, initCost, + activatedScriptVersion) var hashCode = 0 cfor(0)(_ < state.length, _ + 1) { i => hashCode = 31 * hashCode + state(i).hashCode @@ -182,7 +185,7 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, hashCode } - override def toString = s"ErgoLikeContext(lastBlockUtxoRoot=$lastBlockUtxoRoot, headers=$headers, preHeader=$preHeader, dataBoxes=$dataBoxes, boxesToSpend=$boxesToSpend, spendingTransaction=$spendingTransaction, selfIndex=$selfIndex, extension=$extension, validationSettings=$validationSettings, costLimit=$costLimit, initCost=$initCost)" + override def toString = s"ErgoLikeContext(lastBlockUtxoRoot=$lastBlockUtxoRoot, headers=$headers, preHeader=$preHeader, dataBoxes=$dataBoxes, boxesToSpend=$boxesToSpend, spendingTransaction=$spendingTransaction, selfIndex=$selfIndex, extension=$extension, validationSettings=$validationSettings, costLimit=$costLimit, initCost=$initCost, activatedScriptVersion=$activatedScriptVersion)" } object ErgoLikeContext { @@ -191,6 +194,28 @@ object ErgoLikeContext { /** Maximimum number of headers in `headers` collection of the context. */ val MaxHeaders = SigmaConstants.MaxHeaders.value + + /** Copies the given context allowing also to update fields. + * NOTE: it can be used ONLY for instances of ErgoLikeContext. + * @tparam T used here to limit use of this method to only ErgoLikeContext instances + * @return a new instance of [[ErgoLikeContext]]. */ + @inline def copy[T >: ErgoLikeContext <: ErgoLikeContext](ctx: T)( + lastBlockUtxoRoot: AvlTreeData = ctx.lastBlockUtxoRoot, + headers: Coll[Header] = ctx.headers, + preHeader: PreHeader = ctx.preHeader, + dataBoxes: IndexedSeq[ErgoBox] = ctx.dataBoxes, + boxesToSpend: IndexedSeq[ErgoBox] = ctx.boxesToSpend, + spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput] = ctx.spendingTransaction, + selfIndex: Int = ctx.selfIndex, + extension: ContextExtension = ctx.extension, + validationSettings: SigmaValidationSettings = ctx.validationSettings, + costLimit: Long = ctx.costLimit, + initCost: Long = ctx.initCost, + activatedScriptVersion: Byte = ctx.activatedScriptVersion): ErgoLikeContext = { + new ErgoLikeContext( + lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, + spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost, activatedScriptVersion) + } } /** When interpreted evaluates to a ByteArrayConstant built from Context.minerPubkey */ diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index 8745debbd8..cb4e6aaae4 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -152,7 +152,7 @@ trait Interpreter extends ScorexLogging { implicit val vs = context.validationSettings val maxCost = context.costLimit val initCost = context.initCost - trySoftForkable[ReductionResult](whenSoftFork = TrivialProp.TrueProp -> 0) { + trySoftForkable[ReductionResult](whenSoftFork = TrivialProp.TrueProp -> initCost) { val costingRes = doCostingEx(env, exp, true) val costF = costingRes.costF IR.onCostingResult(env, exp, costingRes) @@ -196,7 +196,12 @@ trait Interpreter extends ScorexLogging { context: CTX, env: ScriptEnv): (SigmaBoolean, Long) = { if (context.activatedScriptVersion > Interpreter.MaxSupportedScriptVersion) { - + // majority has already switched to higher version, accept without verification + // NOTE: this path should never be taken for validation of candidate blocks + // this means Ergo node should always pass Interpreter.MaxSupportedScriptVersion + // as the value of ErgoLikeContext.activatedScriptVersion. + // see also ErgoLikeContext ScalaDoc. + return TrivialProp.TrueProp -> context.initCost } else { if (ergoTree.version > context.activatedScriptVersion) throw new InterpreterException(s"Not supported script version ${ergoTree.version}") @@ -358,7 +363,7 @@ object Interpreter { * For example in version 3.x-4.x this value should be 0, in 5.x increased to 1, * in 6.x set to 2, etc. */ - val MaxSupportedScriptVersion: Int = 0 + val MaxSupportedScriptVersion: Byte = 0 def error(msg: String) = throw new InterpreterException(msg) diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index f5bd55f008..b02a103c67 100644 --- a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -3,12 +3,12 @@ package sigmastate import org.ergoplatform.ErgoBox.AdditionalRegisters import org.ergoplatform._ import scorex.util.ModifierId -import sigmastate.Values.ErgoTree.{DefaultHeader, updateVersionBits, SizeFlag} +import sigmastate.Values.ErgoTree.{DefaultHeader, updateVersionBits} import sigmastate.Values._ import sigmastate.eval._ import sigmastate.helpers.ErgoLikeContextTesting import sigmastate.helpers.TestingHelpers.createBox -import sigmastate.interpreter.Interpreter +import sigmastate.interpreter.{Interpreter, ProverResult} import sigmastate.lang.exceptions.InterpreterException import sigmastate.utxo._ import sigmastate.utils.Helpers._ @@ -40,36 +40,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { ) ) - /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action - * -----|----------|-----------|----------------|---------|-------- - * 1 | inactive | candidate | Script v1 | v4.0 | R4.0-AOT-cost, R4.0-AOT-verify - */ - property("Rule 1 | inactive SF | candidate block | Script v1") { - val samples = genSamples[Coll[Box]](collOfN[Box](5), MinSuccessful(20)) - - 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)) - ) - }, - existingFeature({ (x: Coll[Box]) => x.filter({ (b: Box) => b.value > 1 }) }, - "{ (x: Coll[Box]) => x.filter({(b: Box) => b.value > 1 }) }", - FuncValue( - Vector((1, SCollectionType(SBox))), - Filter( - ValUse(1, SCollectionType(SBox)), - FuncValue(Vector((3, SBox)), GT(ExtractAmount(ValUse(3, SBox)), LongConstant(1L))) - ) - )), - preGeneratedSamples = Some(samples)) - - } - def createErgoTree(headerFlags: Byte)(implicit IR: IRContext): ErgoTree = { - import ErgoTree._ val code = s"""{ | val func = { (x: Coll[Box]) => x.filter({(b: Box) => b.value > 1 }) } @@ -108,28 +79,164 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { pr } + def testVerify(ergoTree: ErgoTree, activatedScriptVersion: Byte) = { + val tpeA = SCollection(SBox) + val input = Coll[Box](b1) + val newRegisters: AdditionalRegisters = Map( + ErgoBox.R4 -> Constant[SType](Coll[Box]().asInstanceOf[SType#WrappedType], tpeA) + ) + + val ctx = copyContext(ErgoLikeContextTesting.dummy( + createBox(0, ergoTree, additionalRegisters = newRegisters) + ).withBindings( + 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA) + ).asInstanceOf[ErgoLikeContext])(activatedScriptVersion = activatedScriptVersion) + + val verifier = new ErgoLikeInterpreter() { type CTX = ErgoLikeContext } + val pr = ProverResult(ProverResult.empty.proof, ctx.extension) + + // NOTE: exactly this overload should also be called in Ergo + verifier.verify(ergoTree, ctx, pr, fakeMessage).getOrThrow + } + + def ergoTreeHeader(version: Byte): Byte = { + val h = ErgoTree.SizeFlag | updateVersionBits(DefaultHeader, version) + h.toByte + } + + property("new versions of scripts will require size bit in the header") { + (1 to 7).foreach { version => + assertExceptionThrown( + createErgoTree(headerFlags = updateVersionBits(DefaultHeader, version.toByte)), + { t => + t.isInstanceOf[IllegalArgumentException] && + t.getMessage.contains("For newer version the size bit is required") + }) + } + } + + /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action + * -----|----------|-----------|----------------|---------|-------- + * 1 | inactive | candidate | Script v1 | v4.0 | R4.0-AOT-cost, R4.0-AOT-verify + * 5 | inactive | mined | Script v1 | v4.0 | R4.0-AOT-cost, R4.0-AOT-verify + */ + property("Rules 1,5 | inactive SF | candidate or mined block | Script v1") { + val samples = genSamples[Coll[Box]](collOfN[Box](5), MinSuccessful(20)) + + 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)) + ) + }, + existingFeature({ (x: Coll[Box]) => x.filter({ (b: Box) => b.value > 1 }) }, + "{ (x: Coll[Box]) => x.filter({(b: Box) => b.value > 1 }) }", + FuncValue( + Vector((1, SCollectionType(SBox))), + Filter( + ValUse(1, SCollectionType(SBox)), + FuncValue(Vector((3, SBox)), GT(ExtractAmount(ValUse(3, SBox)), LongConstant(1L))) + ) + )), + preGeneratedSamples = Some(samples)) + + } + /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action * -----|----------|-----------|----------------|---------|-------- * 3 | inactive | candidate | Script v2 | v4.0 | skip-pool-tx (cannot handle) + * 7 | inactive | mined | Script v2 | v4.0 | skip-reject (cannot handle) */ - property("Rule 3 | inactive SF | candidate block | Script v2") { + property("Rules 3, 7 | inactive SF | candidate or mined block | Script v2") { + val headerFlags = ergoTreeHeader( 1 /* Script v2 */) + val ergoTree = createErgoTree(headerFlags = headerFlags) + // both prove and verify are rejecting assertExceptionThrown( - createErgoTree(headerFlags = updateVersionBits(DefaultHeader, 1)), + testProve(ergoTree, activatedScriptVersion = 0 /* SF Status: inactive */), { t => - t.isInstanceOf[IllegalArgumentException] && - t.getMessage.contains("For newer version the size bit is required") + t.isInstanceOf[InterpreterException] && + t.getMessage.contains(s"Not supported script version ${ergoTree.version}") }) - val headerFlags = ErgoTree.SizeFlag | updateVersionBits(DefaultHeader, 1 /* Script v2 */) - val ergoTree = createErgoTree(headerFlags = headerFlags.toByte) - assertExceptionThrown( - testProve(ergoTree, activatedScriptVersion = 0 /* SF Status: inactive */), + testVerify(ergoTree, activatedScriptVersion = 0 /* SF Status: inactive */), { t => t.isInstanceOf[InterpreterException] && - t.getMessage.contains(s"Not supported script version ${ergoTree.version}") + t.getMessage.contains(s"Not supported script version ${ergoTree.version}") }) } + /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action + * -----|----------|-----------|----------------|---------|-------- + * 9 | active | candidate | Script v1 | v4.0 | R4.0-AOT-cost, R4.0-AOT-verify + */ + property("Rule 9 | active SF | candidate block | Script v1") { + val headerFlags = ergoTreeHeader( 0 /* Script v1 */) + val ergoTree = createErgoTree(headerFlags = headerFlags) + + val activatedVersion = 1.toByte // SF Status: active + + // both prove and verify are accepting with full evaluation + val expectedCost = 5464L + val pr = testProve( + ergoTree, + activatedScriptVersion = Interpreter.MaxSupportedScriptVersion // special case for *candidate* block + ) + pr.proof shouldBe Array.emptyByteArray + pr.cost shouldBe expectedCost + + val (ok, cost) = testVerify( + ergoTree, + activatedScriptVersion = Interpreter.MaxSupportedScriptVersion // special case for *candidate* block + ) + ok shouldBe true + cost shouldBe expectedCost + } + + /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action + * -----|----------|-----------|----------------|---------|-------- + * 11 | active | candidate | Script v2 | v4.0 | skip-pool-tx (cannot handle) + * 15 | active | mined | Script v2 | v4.0 | skip-accept (rely on majority) + */ + property("Rule 11, 15 | active SF | candidate or mined block | Script v2") { + val headerFlags = ergoTreeHeader( 1 /* Script v2 */) + val ergoTree = createErgoTree(headerFlags = headerFlags) + + val activatedVersion = 1.toByte // SF Status: active + + // both prove and verify are accepting without evaluation + val expectedCost = 0L + val pr = testProve(ergoTree, activatedScriptVersion = activatedVersion) + pr.proof shouldBe Array.emptyByteArray + pr.cost shouldBe expectedCost + + val (ok, cost) = testVerify(ergoTree, activatedScriptVersion = activatedVersion) + ok shouldBe true + cost shouldBe expectedCost + } + + /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action + * -----|----------|-----------|----------------|---------|-------- + * 13 | active | mined | Script v1 | v4.0 | skip-accept (rely on majority) + */ + property("Rule 13 | active SF | mined block | Script v1") { + val headerFlags = ergoTreeHeader( 0 /* Script v1 */) + val ergoTree = createErgoTree(headerFlags = headerFlags) + + val activatedVersion = 1.toByte // SF Status: active + + // both prove and verify are accepting without evaluation + val expectedCost = 0L + val pr = testProve(ergoTree, activatedScriptVersion = activatedVersion) + pr.proof shouldBe Array.emptyByteArray + pr.cost shouldBe expectedCost + + val (ok, cost) = testVerify(ergoTree, activatedScriptVersion = activatedVersion) + ok shouldBe true + cost shouldBe expectedCost + } + } From b4b60cb42fa47788985db4307daeef38a3cee87e Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 17 Nov 2020 16:24:18 +0300 Subject: [PATCH 06/31] towards-v4.0:l fix after merge --- .../scala/sigmastate/ScriptVersionSwitchSpecification.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index b02a103c67..3dff63009c 100644 --- a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -125,7 +125,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { verifyCases( { - def success[T](v: T, c: Int) = Success(Expected(v, c)) + def success[T](v: T, c: Int) = Expected(Success(v), c) Seq( (Coll[Box](), success(Coll[Box](), 37297)), (Coll[Box](b1), success(Coll[Box](), 37397)) From 3d4afeed213182baabf4faab948180be5df830c3 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 17 Nov 2020 17:16:17 +0300 Subject: [PATCH 07/31] towards-v4.0: fixes after review --- .../src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 4 ++-- .../org/ergoplatform/validation/ValidationRules.scala | 6 ++++++ .../main/scala/sigmastate/interpreter/Interpreter.scala | 7 ++++++- .../scala/sigmastate/interpreter/InterpreterContext.scala | 2 +- .../sigmastate/ScriptVersionSwitchSpecification.scala | 4 +++- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 1a6ba6746a..f6faa59754 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -28,11 +28,11 @@ import spire.syntax.all.cfor * @param boxesToSpend - boxes, that corresponds to id's of `spendingTransaction.inputs` * @param spendingTransaction - transaction that contains `self` box * @param extension - prover-defined key-value pairs, that may be used inside a script - * @param validationSettings validataion parameters passed to Interpreter.verify to detect soft-fork conditions + * @param validationSettings validation parameters passed to Interpreter.verify to detect soft-fork conditions * @param costLimit hard limit on accumulated execution cost, if exceeded lead to CostLimitException to be thrown * @param initCost initial value of execution cost already accumulated before Interpreter.verify is called * @param activatedScriptVersion Maximum version of ErgoTree currently activated on the network. - * The activation is performed via miners voting majority switches to higher version. + * The activation is performed via miners voting. * For verification of *mined* blocks this parameter should be passed according * to the latest voted (activated) script version on the network. * However this is not the case for *candidate* blocks. diff --git a/sigmastate/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/sigmastate/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index 33f17b3add..c4604fef5f 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -76,6 +76,12 @@ case class ValidationException(message: String, rule: ValidationRule, args: Seq[ override def fillInStackTrace(): Throwable = this // to avoid spending time on recording stack trace } +/** All validation rules which are used to check soft-forkable conditions. Each validation + * rule throws a [[org.ergoplatform.validation.ValidationException]]. Each + * ValidationException can be caught and handled with respect to + * [[SigmaValidationSettings]], which can be changed by miners via voting. + * Thus, the behavior of the rules can be overridden without breaking consensus. + */ object ValidationRules { /** The id of the first validation rule. Can be used as the beginning of the rules id range. */ val FirstRuleId = 1000.toShort diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index cb4e6aaae4..ccd97d48f7 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -195,10 +195,13 @@ trait Interpreter extends ScorexLogging { def fullReduction(ergoTree: ErgoTree, context: CTX, env: ScriptEnv): (SigmaBoolean, Long) = { + // The following conditions define behavior which depend on the version of ergoTree + // This works in addition to more fine-grained soft-forkabiltiy mechanism implemented + // using ValidationRules (see trySoftForkable method call here and in reduceToCrypto). if (context.activatedScriptVersion > Interpreter.MaxSupportedScriptVersion) { // majority has already switched to higher version, accept without verification // NOTE: this path should never be taken for validation of candidate blocks - // this means Ergo node should always pass Interpreter.MaxSupportedScriptVersion + // in which case Ergo node should always pass Interpreter.MaxSupportedScriptVersion // as the value of ErgoLikeContext.activatedScriptVersion. // see also ErgoLikeContext ScalaDoc. return TrivialProp.TrueProp -> context.initCost @@ -206,6 +209,7 @@ trait Interpreter extends ScorexLogging { if (ergoTree.version > context.activatedScriptVersion) throw new InterpreterException(s"Not supported script version ${ergoTree.version}") } + implicit val vs: SigmaValidationSettings = context.validationSettings val initCost = JMath.addExact(ergoTree.complexity.toLong, context.initCost) @@ -216,6 +220,7 @@ trait Interpreter extends ScorexLogging { val contextWithCost = context.withInitCost(initCost).asInstanceOf[CTX] val prop = propositionFromErgoTree(ergoTree, contextWithCost) + val (propTree, context2) = trySoftForkable[(BoolValue, CTX)](whenSoftFork = (TrueLeaf, contextWithCost)) { applyDeserializeContext(contextWithCost, prop) } diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index cd36634e24..c4f58453dc 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -53,7 +53,7 @@ trait InterpreterContext { /** Prover-defined key-value pairs, that may be used inside a script. */ val extension: ContextExtension - /** Validataion parameters passed to Interpreter.verify to detect soft-fork conditions. */ + /** Validation parameters passed to Interpreter.verify to detect soft-fork conditions. */ val validationSettings: SigmaValidationSettings /** Hard limit on accumulated execution cost. Exceeding it leads to CostLimitException diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index 3dff63009c..cf9ae93fee 100644 --- a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -177,7 +177,9 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { val headerFlags = ergoTreeHeader( 0 /* Script v1 */) val ergoTree = createErgoTree(headerFlags = headerFlags) - val activatedVersion = 1.toByte // SF Status: active + // Even though the SF is active and the v2 scripts can be accepted in `mined` blocks + // this test case is for `candidate` block, so we MUST use + // Interpreter.MaxSupportedScriptVersion // both prove and verify are accepting with full evaluation val expectedCost = 5464L From dc4b1e2e291bca3241f57e99d9e40d2f0248dfa5 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 19 Nov 2020 16:28:02 +0300 Subject: [PATCH 08/31] towards-v4.0: TODO added for script version conditions --- .../src/main/scala/sigmastate/interpreter/Interpreter.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index ccd97d48f7..962569ac43 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -195,11 +195,12 @@ trait Interpreter extends ScorexLogging { def fullReduction(ergoTree: ErgoTree, context: CTX, env: ScriptEnv): (SigmaBoolean, Long) = { + // TODO v5.0: the condition below should be revised if necessary // The following conditions define behavior which depend on the version of ergoTree // This works in addition to more fine-grained soft-forkabiltiy mechanism implemented // using ValidationRules (see trySoftForkable method call here and in reduceToCrypto). if (context.activatedScriptVersion > Interpreter.MaxSupportedScriptVersion) { - // majority has already switched to higher version, accept without verification + // > 90% has already switched to higher version, accept without verification // NOTE: this path should never be taken for validation of candidate blocks // in which case Ergo node should always pass Interpreter.MaxSupportedScriptVersion // as the value of ErgoLikeContext.activatedScriptVersion. From 1e81d0e148e5fc685c5096d1fa5c7c3ff263e331 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 26 Nov 2020 16:01:59 +0300 Subject: [PATCH 09/31] towards-v4.0: VersionContext field added to SigmaByteReader --- .../interpreter/InterpreterContext.scala | 10 ++++++++-- .../sigmastate/utils/SigmaByteReader.scala | 20 ++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index c4f58453dc..682b00df8d 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -1,9 +1,9 @@ package sigmastate.interpreter import org.ergoplatform.validation.SigmaValidationSettings +import scalan.Nullable import sigmastate.SType import sigmastate.Values.EvaluatedValue -import sigmastate.eval.Evaluation import sigmastate.serialization.SigmaSerializer import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import special.sigma @@ -36,7 +36,11 @@ object ContextExtension { } override def parse(r: SigmaByteReader): ContextExtension = { - val extSize = r.getByte() + val extSize = r.versionContext match { + case Nullable(_) => r.getUByte() // v4.0 and above + case _ => r.getByte() // v3.x + } + val ext = (0 until extSize) .map(_ => (r.getByte(), r.getValue().asInstanceOf[EvaluatedValue[_ <: SType]])) .toMap[Byte, EvaluatedValue[_ <: SType]] @@ -102,3 +106,5 @@ trait InterpreterContext { */ def toSigmaContext(isCost: Boolean, extensions: Map[Byte, AnyValue] = Map()): sigma.Context } + +case class VersionContext(ergoProtocolVersion: Byte, scriptVersion: Byte) diff --git a/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala index cf51dd8b5d..1ce6729964 100644 --- a/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala +++ b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala @@ -1,17 +1,35 @@ package sigmastate.utils +import scalan.Nullable import scorex.util.serialization.Reader import sigmastate.SType import sigmastate.Values.{SValue, Value} import sigmastate.lang.exceptions.{InputSizeLimitExceeded, DeserializeCallDepthExceeded} import sigmastate.serialization._ import scorex.util.Extensions._ +import sigmastate.interpreter.VersionContext import spire.syntax.all.cfor +/** Reader used in the concrete implementations of [[SigmaSerializer]]. + * It decorates the given reader, delegates most of the methods to it, but also adds new + * methods. + * + * @param r the underlying reader this reader reads from + * @param constantStore the store of constants which is used to resolve + * [[sigmastate.Values.ConstantPlaceholder]] + * @param resolvePlaceholdersToConstants if true then resolved constants will be + * substituted in the tree instead of the placeholder. + * @param maxTreeDepth limit on the tree depth (recursive invocations) + * of the deserializer + * @param versionContext optional version context to support soft and + * hard forks in serialization logic. + * If None, then no SF or HF activated. + */ class SigmaByteReader(val r: Reader, var constantStore: ConstantStore, var resolvePlaceholdersToConstants: Boolean, - val maxTreeDepth: Int = SigmaSerializer.MaxTreeDepth) + val maxTreeDepth: Int = SigmaSerializer.MaxTreeDepth, + val versionContext: Nullable[VersionContext] = Nullable.None) extends Reader { @inline private def checkPositionLimit(): Unit = From de3fa900a37bae915844602010e7310ca7087cb3 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 26 Nov 2020 17:30:02 +0300 Subject: [PATCH 10/31] towards-v4.0: tests for VersionContext --- .../interpreter/InterpreterContext.scala | 13 +++++++++ .../serialization/SigmaSerializer.scala | 29 ++++++++++++++----- .../ErgoLikeTransactionSpec.scala | 27 +++++++++++++---- .../BlockSerializerSpecification.scala | 3 +- .../ErgoTreeSerializerSpecification.scala | 8 +++-- 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index 2863133033..714e4bbe56 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -106,4 +106,17 @@ trait InterpreterContext { def toSigmaContext(isCost: Boolean, extensions: Map[Byte, AnyValue] = Map()): sigma.Context } +/** Descriptor of protocol versions. + * @param ergoProtocolVersion the version of Ergo protocol (see Header.version) + * @param scriptVersion the version of ErgoTree (see ErgoTree.header) + */ case class VersionContext(ergoProtocolVersion: Byte, scriptVersion: Byte) + +object VersionContext { + val MaxSupportedErgoProtocol: Byte = 2 + + /** Descriptor of the max supported versions. */ + val MaxSupportedVersion = VersionContext( + ergoProtocolVersion = MaxSupportedErgoProtocol, + scriptVersion = Interpreter.MaxSupportedScriptVersion) +} diff --git a/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala index 6e9dc86f4a..93eb000803 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala @@ -4,10 +4,12 @@ import java.nio.ByteBuffer import org.ergoplatform.SigmaConstants import org.ergoplatform.validation.SigmaValidationSettings +import scalan.Nullable import scorex.util.ByteArrayBuilder import sigmastate.lang.exceptions.SerializerException import sigmastate.utils._ import scorex.util.serialization._ +import sigmastate.interpreter.VersionContext import sigmastate.serialization.OpCodes.OpCode object SigmaSerializer { @@ -17,29 +19,42 @@ object SigmaSerializer { val MaxPropositionSize: Int = SigmaConstants.MaxPropositionBytes.value val MaxTreeDepth: Int = SigmaConstants.MaxTreeDepth.value - /** Helper function to be use in serializers. + //TODO v5.0: remove default value of versionContext parameter + // All usages of this method should pass a version context explicitly. + + /** Helper function to be use in serializers. * Starting position is marked and then used to compute number of consumed bytes. * val r = Serializer.startReader(bytes, pos) * val obj = r.getValue() - * obj -> r.consumed */ - def startReader(bytes: Array[Byte], pos: Int = 0): SigmaByteReader = { + * obj -> r.consumed + */ + def startReader(bytes: Array[Byte], + pos: Int = 0, + versionContext: Nullable[VersionContext] = Nullable.None): SigmaByteReader = { val buf = ByteBuffer.wrap(bytes) buf.position(pos) - val r = new SigmaByteReader(new VLQByteBufferReader(buf), + val r = new SigmaByteReader( + new VLQByteBufferReader(buf), new ConstantStore(), resolvePlaceholdersToConstants = false, - maxTreeDepth = MaxTreeDepth).mark() + maxTreeDepth = MaxTreeDepth, + versionContext = versionContext + ).mark() r } + /** Helper function to be use in serializers. */ def startReader(bytes: Array[Byte], constantStore: ConstantStore, - resolvePlaceholdersToConstants: Boolean)(implicit vs: SigmaValidationSettings): SigmaByteReader = { + resolvePlaceholdersToConstants: Boolean, + versionContext: Nullable[VersionContext]) + (implicit vs: SigmaValidationSettings): SigmaByteReader = { val buf = ByteBuffer.wrap(bytes) val r = new SigmaByteReader(new VLQByteBufferReader(buf), constantStore, resolvePlaceholdersToConstants, - maxTreeDepth = MaxTreeDepth).mark() + maxTreeDepth = MaxTreeDepth, + versionContext = versionContext).mark() r } diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala index c57e48e414..c537fd23ba 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala @@ -2,12 +2,13 @@ package org.ergoplatform import org.ergoplatform.ErgoBox.TokenId import org.ergoplatform.settings.ErgoAlgos +import scalan.Nullable import scorex.crypto.hash.Digest32 import scorex.util.{Random, ModifierId} import sigmastate.SCollection.SByteArray import sigmastate.{SSigmaProp, SPair, SInt, TrivialProp, SType} -import sigmastate.Values.{LongConstant, FalseLeaf, ConstantNode, SigmaPropConstant, ConstantPlaceholder, TrueSigmaProp, ByteArrayConstant, ErgoTree} -import sigmastate.interpreter.{ProverResult, ContextExtension} +import sigmastate.Values.{LongConstant, FalseLeaf, ConstantNode, SigmaPropConstant, ConstantPlaceholder, TrueSigmaProp, ByteArrayConstant, IntConstant, ErgoTree} +import sigmastate.interpreter.{ProverResult, ContextExtension, VersionContext} import sigmastate.serialization.SigmaSerializer import sigmastate.eval._ import sigmastate.eval.Extensions._ @@ -272,13 +273,27 @@ class ErgoLikeTransactionSpec extends SigmaDslTesting { property("context extension serialization") { forAll { tx: ErgoLikeTransaction => - val ce = ContextExtension((Byte.MinValue to (Byte.MaxValue - 1)).map(i => i.toByte -> IntConstant(4)).toMap) + val idRange = Byte.MinValue to (Byte.MaxValue - 1) + val ce = ContextExtension(idRange.map(id => id.toByte -> IntConstant(4)).toMap) val wrongInput = Input(tx.inputs.head.boxId, ProverResult(Array.emptyByteArray, ce)) val ins = IndexedSeq(wrongInput) ++ tx.inputs.tail val tx2 = tx.clone(inputs = ins) - val bs = ErgoLikeTransactionSerializer.toBytes(tx2) - val restored = ErgoLikeTransactionSerializer.fromBytes(bs) - restored.inputs.head.extension.values.size shouldBe tx2.inputs.head.extension.values.size + def roundtrip(version: Nullable[VersionContext]) = { + val bs = ErgoLikeTransactionSerializer.toBytes(tx2) + val restored = ErgoLikeTransactionSerializer.parse( + SigmaSerializer.startReader(bs, 0, version) + ) + restored.inputs.head.extension.values.size shouldBe tx2.inputs.head.extension.values.size + } + + // successful for v4.0 and above + roundtrip(Nullable(VersionContext.MaxSupportedVersion)) + + // unsuccessful if version context is not passed (which means v3.x version) + assertExceptionThrown( + roundtrip(Nullable.None), + { _ => true } + ) } } } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala index 94890a1bb9..9ac361db1a 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala @@ -1,6 +1,7 @@ package sigmastate.serialization import org.scalacheck.Gen +import scalan.Nullable import sigmastate.SType import sigmastate.Values.Constant import sigmastate.lang.{DeserializationSigmaBuilder, SigmaBuilder} @@ -27,7 +28,7 @@ class BlockSerializerSpecification extends SerializationSpecification { val s = ConstantPlaceholderSerializer(DeserializationSigmaBuilder.mkConstantPlaceholder) val w = SigmaSerializer.startWriter() s.serialize(placeholder, w) - val r = SigmaSerializer.startReader(w.toBytes, store, resolvePlaceholdersToConstants = false) + val r = SigmaSerializer.startReader(w.toBytes, store, resolvePlaceholdersToConstants = false, Nullable.None) s.parse(r) shouldEqual placeholder } } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala index 65259dd36e..55ac192c24 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala @@ -2,6 +2,7 @@ package sigmastate.serialization import java.math.BigInteger +import scalan.Nullable import sigmastate.Values.{ShortConstant, LongConstant, BigIntConstant, SigmaPropValue, IntConstant, ErgoTree, ByteConstant} import sigmastate._ import sigmastate.eval.{IRContext, CBigInt} @@ -41,8 +42,11 @@ class ErgoTreeSerializerSpecification extends SerializationSpecification val (_, _, deserializedConstants, treeBytes) = DefaultSerializer .deserializeHeaderWithTreeBytes(SigmaSerializer.startReader(bytes)) deserializedConstants shouldEqual ergoTree.constants - val r = SigmaSerializer.startReader(treeBytes, new ConstantStore(deserializedConstants), - resolvePlaceholdersToConstants = true) + val r = SigmaSerializer.startReader( + treeBytes, + new ConstantStore(deserializedConstants), + resolvePlaceholdersToConstants = true, + versionContext = Nullable.None) val deserializedTree = ValueSerializer.deserialize(r) deserializedTree shouldEqual tree } From eb23ad110d56594720051e1185ef04c33a1e724b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 27 Nov 2020 12:26:10 +0300 Subject: [PATCH 11/31] towards-v4.0: copyTransaction method --- .../org/ergoplatform/ErgoLikeTransaction.scala | 8 -------- .../ergoplatform/ErgoLikeTransactionSpec.scala | 3 ++- .../sigmastate/helpers/TestingHelpers.scala | 16 ++++++++++++++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala index f05c6e5a15..c5d850d457 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeTransaction.scala @@ -105,14 +105,6 @@ class ErgoLikeTransaction(override val inputs: IndexedSeq[Input], } override def hashCode(): Int = id.hashCode() - - /** Similar to case class `copy` method. Different name is used to not interfere with - * possible derived case classes. - */ - def clone(inputs: IndexedSeq[Input] = inputs, - dataInputs: IndexedSeq[DataInput] = dataInputs, - outputCandidates: IndexedSeq[ErgoBoxCandidate] = outputCandidates) = - new ErgoLikeTransaction(inputs, dataInputs, outputCandidates) } object ErgoLikeTransactionSerializer extends SigmaSerializer[ErgoLikeTransaction, ErgoLikeTransaction] { diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala index c537fd23ba..432e0d01df 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala @@ -13,6 +13,7 @@ import sigmastate.serialization.SigmaSerializer import sigmastate.eval._ import sigmastate.eval.Extensions._ import sigmastate.SType._ +import sigmastate.helpers.TestingHelpers.copyTransaction import sigmastate.utils.Helpers import special.sigma.SigmaDslTesting @@ -277,7 +278,7 @@ class ErgoLikeTransactionSpec extends SigmaDslTesting { val ce = ContextExtension(idRange.map(id => id.toByte -> IntConstant(4)).toMap) val wrongInput = Input(tx.inputs.head.boxId, ProverResult(Array.emptyByteArray, ce)) val ins = IndexedSeq(wrongInput) ++ tx.inputs.tail - val tx2 = tx.clone(inputs = ins) + val tx2 = copyTransaction(tx)(inputs = ins) def roundtrip(version: Nullable[VersionContext]) = { val bs = ErgoLikeTransactionSerializer.toBytes(tx2) val restored = ErgoLikeTransactionSerializer.parse( diff --git a/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala b/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala index b8a51520ac..119572e737 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/TestingHelpers.scala @@ -3,7 +3,7 @@ package sigmastate.helpers import scorex.crypto.hash.Digest32 import special.collection.Coll import scorex.util.ModifierId -import org.ergoplatform.{ErgoLikeTransactionTemplate, ErgoLikeTransaction, ErgoLikeContext, UnsignedInput, ErgoBox, DataInput, ErgoBoxCandidate} +import org.ergoplatform.{ErgoLikeTransactionTemplate, ErgoLikeTransaction, ErgoLikeContext, UnsignedInput, Input, ErgoBox, DataInput, ErgoBoxCandidate} import sigmastate.Values.ErgoTree import org.ergoplatform.ErgoBox.{AdditionalRegisters, allZerosModifierId, TokenId} import org.ergoplatform.validation.SigmaValidationSettings @@ -56,6 +56,17 @@ object TestingHelpers { new ErgoBox(value, ergoTree, additionalTokens, additionalRegisters, transactionId, index, creationHeight) } + /** Copies the given transaction allowing also to update fields. + * NOTE: it can be used ONLY for instances of ErgoLikeTransaction. + * @tparam T used here to limit use of this method to only ErgoLikeTransaction instances + * @return a new instance of [[ErgoLikeTransaction]]. */ + def copyTransaction[T >: ErgoLikeTransaction <: ErgoLikeTransaction](tx: T)( + inputs: IndexedSeq[Input] = tx.inputs, + dataInputs: IndexedSeq[DataInput] = tx.dataInputs, + outputCandidates: IndexedSeq[ErgoBoxCandidate] = tx.outputCandidates) = { + new ErgoLikeTransaction(inputs, dataInputs, outputCandidates) + } + /** Copies the given context allowing also to update fields. */ def copyContext(ctx: ErgoLikeContext)( lastBlockUtxoRoot: AvlTreeData = ctx.lastBlockUtxoRoot, @@ -72,7 +83,8 @@ object TestingHelpers { activatedScriptVersion: Byte = ctx.activatedScriptVersion): ErgoLikeContext = { new ErgoLikeContext( lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, - spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost, activatedScriptVersion) + spendingTransaction, selfIndex, extension, validationSettings, + costLimit, initCost, activatedScriptVersion) } /** Creates a new box by updating some of the additional registers with the given new bindings. From aa4825baee92171a0caaa2f2115fc5d20c42e004 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 11 Dec 2020 18:29:36 +0300 Subject: [PATCH 12/31] towards-v4.0: removed ergoProtocolVersion from VersionContext --- .../src/main/scala/sigmastate/Values.scala | 7 +++++ .../sigmastate/interpreter/Interpreter.scala | 20 +++++++++----- .../interpreter/InterpreterContext.scala | 5 +--- .../ScriptVersionSwitchSpecification.scala | 27 ++++++++----------- .../scala/special/sigma/SigmaDslTesting.scala | 20 +++++++++++--- 5 files changed, 49 insertions(+), 30 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index d14045a758..71f4b5f014 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -1058,6 +1058,13 @@ object Values { (header | version).toByte } + @inline def headerWithVersion(version: Byte): Byte = { + var h = updateVersionBits(DefaultHeader, version) + if (version > 0) + h = (h | ErgoTree.SizeFlag).toByte + h + } + def substConstants(root: SValue, constants: IndexedSeq[Constant[SType]]): SValue = { val store = new ConstantStore(constants) val substRule = strategy[Any] { diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index 962569ac43..e283acb10d 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -207,8 +207,13 @@ trait Interpreter extends ScorexLogging { // see also ErgoLikeContext ScalaDoc. return TrivialProp.TrueProp -> context.initCost } else { - if (ergoTree.version > context.activatedScriptVersion) - throw new InterpreterException(s"Not supported script version ${ergoTree.version}") + // activated version is within the supported range [0..MaxSupportedScriptVersion] + // however + if (ergoTree.version > context.activatedScriptVersion) { + throw new InterpreterException( + s"ErgoTree version ${ergoTree.version} is higher than activated ${context.activatedScriptVersion}") + } + // else proceed normally } implicit val vs: SigmaValidationSettings = context.validationSettings @@ -365,11 +370,14 @@ object Interpreter { /** Maximum version of ErgoTree supported by this interpreter release. * See version bits in `ErgoTree.header` for more details. - * This value should be increased with each new language update via soft-fork. - * For example in version 3.x-4.x this value should be 0, in 5.x increased to 1, - * in 6.x set to 2, etc. + * This value should be increased with each new protocol update via soft-fork. + * The following values are used for current and upcoming forks: + * - version 3.x this value must be 0 + * - in v4.0 must be 1 + * - in v5.x must be 2 + * etc. */ - val MaxSupportedScriptVersion: Byte = 0 + val MaxSupportedScriptVersion: Byte = 1 // supported versions 0 and 1 def error(msg: String) = throw new InterpreterException(msg) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index 714e4bbe56..ab414a78e3 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -107,16 +107,13 @@ trait InterpreterContext { } /** Descriptor of protocol versions. - * @param ergoProtocolVersion the version of Ergo protocol (see Header.version) * @param scriptVersion the version of ErgoTree (see ErgoTree.header) */ -case class VersionContext(ergoProtocolVersion: Byte, scriptVersion: Byte) +case class VersionContext(scriptVersion: Byte) object VersionContext { - val MaxSupportedErgoProtocol: Byte = 2 /** Descriptor of the max supported versions. */ val MaxSupportedVersion = VersionContext( - ergoProtocolVersion = MaxSupportedErgoProtocol, scriptVersion = Interpreter.MaxSupportedScriptVersion) } diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index cf9ae93fee..37e3de2943 100644 --- a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -99,11 +99,6 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { verifier.verify(ergoTree, ctx, pr, fakeMessage).getOrThrow } - def ergoTreeHeader(version: Byte): Byte = { - val h = ErgoTree.SizeFlag | updateVersionBits(DefaultHeader, version) - h.toByte - } - property("new versions of scripts will require size bit in the header") { (1 to 7).foreach { version => assertExceptionThrown( @@ -123,6 +118,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { property("Rules 1,5 | inactive SF | candidate or mined block | Script v1") { val samples = genSamples[Coll[Box]](collOfN[Box](5), MinSuccessful(20)) + // this execution corresponds to the normal validation action (R4.0-AOT-cost, R4.0-AOT-verify) verifyCases( { def success[T](v: T, c: Int) = Expected(Success(v), c) @@ -141,7 +137,6 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { ) )), preGeneratedSamples = Some(samples)) - } /** Rule#| SF Status| Block Type| Script Version | Release | Validation Action @@ -150,22 +145,22 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { * 7 | inactive | mined | Script v2 | v4.0 | skip-reject (cannot handle) */ property("Rules 3, 7 | inactive SF | candidate or mined block | Script v2") { - val headerFlags = ergoTreeHeader( 1 /* Script v2 */) + val headerFlags = ErgoTree.headerWithVersion( 2 /* Script v2 */) val ergoTree = createErgoTree(headerFlags = headerFlags) // both prove and verify are rejecting assertExceptionThrown( - testProve(ergoTree, activatedScriptVersion = 0 /* SF Status: inactive */), + testProve(ergoTree, activatedScriptVersion = 1 /* SF Status: inactive */), { t => t.isInstanceOf[InterpreterException] && - t.getMessage.contains(s"Not supported script version ${ergoTree.version}") + t.getMessage.contains(s"ErgoTree version ${ergoTree.version} is higher than activated 1") }) assertExceptionThrown( - testVerify(ergoTree, activatedScriptVersion = 0 /* SF Status: inactive */), + testVerify(ergoTree, activatedScriptVersion = 1 /* SF Status: inactive */), { t => t.isInstanceOf[InterpreterException] && - t.getMessage.contains(s"Not supported script version ${ergoTree.version}") + t.getMessage.contains(s"ErgoTree version ${ergoTree.version} is higher than activated 1") }) } @@ -174,7 +169,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { * 9 | active | candidate | Script v1 | v4.0 | R4.0-AOT-cost, R4.0-AOT-verify */ property("Rule 9 | active SF | candidate block | Script v1") { - val headerFlags = ergoTreeHeader( 0 /* Script v1 */) + val headerFlags = ErgoTree.headerWithVersion( 1 /* Script v1 */) val ergoTree = createErgoTree(headerFlags = headerFlags) // Even though the SF is active and the v2 scripts can be accepted in `mined` blocks @@ -204,10 +199,10 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { * 15 | active | mined | Script v2 | v4.0 | skip-accept (rely on majority) */ property("Rule 11, 15 | active SF | candidate or mined block | Script v2") { - val headerFlags = ergoTreeHeader( 1 /* Script v2 */) + val headerFlags = ErgoTree.headerWithVersion( 2 /* Script v2 */) val ergoTree = createErgoTree(headerFlags = headerFlags) - val activatedVersion = 1.toByte // SF Status: active + val activatedVersion = 2.toByte // SF Status: active // both prove and verify are accepting without evaluation val expectedCost = 0L @@ -225,10 +220,10 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { * 13 | active | mined | Script v1 | v4.0 | skip-accept (rely on majority) */ property("Rule 13 | active SF | mined block | Script v1") { - val headerFlags = ergoTreeHeader( 0 /* Script v1 */) + val headerFlags = ErgoTree.headerWithVersion( 1 /* Script v1 */) val ergoTree = createErgoTree(headerFlags = headerFlags) - val activatedVersion = 1.toByte // SF Status: active + val activatedVersion = 2.toByte // SF Status: active // both prove and verify are accepting without evaluation val expectedCost = 0L diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala index 3c9265cb3c..cbde55ad69 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala @@ -249,11 +249,22 @@ class SigmaDslTesting extends PropSpec extension, validationSettings, costLimit, initCost) } - /** Executes the default feature verification wrapper script using: - * 1) the given input - * 2) the given expected results (values and costs) + /** Executes the default feature verification wrapper script. + * @param input the given input + * @param expected the given expected results (values and costs) */ def checkVerify(input: A, expected: Expected[B]): Unit = { + checkVerifyVersion(input, expected, 0) + checkVerifyVersion(input, expected, 1) + } + + /** Executes the default feature verification wrapper script for the specific ErgoTree + * version. + * @param input the given input + * @param expected the given expected results (values and costs) + * @param scriptVersion version to use when the test ErgoTree is created + */ + def checkVerifyVersion(input: A, expected: Expected[B], scriptVersion: Byte): Unit = { val tpeA = Evaluation.rtypeToSType(oldF.tA) val tpeB = Evaluation.rtypeToSType(oldF.tB) @@ -291,7 +302,8 @@ class SigmaDslTesting extends PropSpec pkAlice, DeserializeRegister(ErgoBox.R5, SSigmaProp), // deserialize pkBob DeserializeContext(2, SSigmaProp))) // deserialize pkCarol - ErgoTree.fromProposition(sigmastate.SigmaOr(prop, multisig)) + val header = ErgoTree.headerWithVersion(scriptVersion) + ErgoTree.withSegregation(header, sigmastate.SigmaOr(prop, multisig)) } val pkBobBytes = ValueSerializer.serialize(prover.pubKeys(1).toSigmaProp) From 11042692a361dd167a10dcdcffd6878f66dad1ac Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 11 Dec 2020 20:25:31 +0300 Subject: [PATCH 13/31] towards-v4.0: remove default for activatedScriptVersion and update Encoder/Decoder --- .../main/scala/org/ergoplatform/ErgoLikeContext.scala | 2 +- .../src/main/scala/org/ergoplatform/JsonCodecs.scala | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index f6faa59754..e94aa30937 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -54,7 +54,7 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val validationSettings: SigmaValidationSettings, val costLimit: Long, val initCost: Long, - val activatedScriptVersion: Byte = Interpreter.MaxSupportedScriptVersion + val activatedScriptVersion: Byte ) extends InterpreterContext { // TODO lastBlockUtxoRoot should be calculated from headers if it is nonEmpty diff --git a/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala b/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala index 7391f8e324..44997fb171 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -400,7 +400,8 @@ trait JsonCodecs { "extension" -> ctx.extension.asJson, "validationSettings" -> ctx.validationSettings.asJson, "costLimit" -> ctx.costLimit.asJson, - "initCost" -> ctx.initCost.asJson + "initCost" -> ctx.initCost.asJson, + "activatedVersion" -> ctx.activatedScriptVersion.asJson ) }) @@ -417,7 +418,11 @@ trait JsonCodecs { validationSettings <- cursor.downField("validationSettings").as[SigmaValidationSettings] costLimit <- cursor.downField("costLimit").as[Long] initCost <- cursor.downField("initCost").as[Long] - } yield new ErgoLikeContext(lastBlockUtxoRoot, Colls.fromArray(headers.toArray), preHeader, - dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost) + version <- cursor.downField("activatedVersion").as[Byte] + } yield new ErgoLikeContext( + lastBlockUtxoRoot, Colls.fromArray(headers.toArray), preHeader, + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, + validationSettings, costLimit, initCost, version + ) }) } From 19c106ea1821d978f73b22d04c5af852965ba088 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 11 Dec 2020 21:41:45 +0300 Subject: [PATCH 14/31] towards-v4.0: remove default for activatedScriptVersion (part 2) --- .../sigmastate/CostingSpecification.scala | 18 ++++++++++-------- .../src/test/scala/sigmastate/TestsBase.scala | 9 +++++++++ .../helpers/ErgoLikeContextTesting.scala | 15 ++++++++++----- .../generators/ObjectGenerators.scala | 10 +++++++--- .../scala/special/sigma/SigmaDslTesting.scala | 3 ++- .../scala/special/sigma/SigmaTestingData.scala | 3 ++- 6 files changed, 40 insertions(+), 18 deletions(-) create mode 100644 sigmastate/src/test/scala/sigmastate/TestsBase.scala diff --git a/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala index 4a3da0ad2b..9738ddf98c 100644 --- a/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala @@ -13,7 +13,7 @@ import sigmastate.eval.Sized._ import sigmastate.eval._ import sigmastate.helpers.TestingHelpers._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter} -import sigmastate.interpreter.ContextExtension +import sigmastate.interpreter.{ContextExtension, Interpreter} import sigmastate.interpreter.Interpreter.{ScriptNameProp, ScriptEnv, emptyEnv} import sigmastate.utxo.CostTable import sigmastate.utxo.CostTable._ @@ -62,13 +62,15 @@ class CostingSpecification extends SigmaTestingData { 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( - lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, - headers = headers, preHeader = preHeader, - dataBoxes = IndexedSeq(dataBox), - boxesToSpend = IndexedSeq(selfBox), - spendingTransaction = tx, selfIndex = 0, extension, ValidationRules.currentSettings, ScriptCostLimit.value, CostTable.interpreterInitCost) + lazy val context = new ErgoLikeContext( + lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, + headers = headers, preHeader = preHeader, + dataBoxes = IndexedSeq(dataBox), + boxesToSpend = IndexedSeq(selfBox), + spendingTransaction = tx, selfIndex = 0, extension, + ValidationRules.currentSettings, ScriptCostLimit.value, + CostTable.interpreterInitCost, ActivatedVersionInTest + ) def cost(script: String)(expCost: Int): Unit = { val ergoTree = compiler.compile(env, script) diff --git a/sigmastate/src/test/scala/sigmastate/TestsBase.scala b/sigmastate/src/test/scala/sigmastate/TestsBase.scala new file mode 100644 index 0000000000..ca723717ae --- /dev/null +++ b/sigmastate/src/test/scala/sigmastate/TestsBase.scala @@ -0,0 +1,9 @@ +package sigmastate + +import sigmastate.interpreter.Interpreter + +trait TestsBase { + + val ActivatedVersionInTest = Interpreter.MaxSupportedScriptVersion + +} diff --git a/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala index 97f355331c..91974ff196 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala @@ -6,7 +6,7 @@ import org.ergoplatform._ import org.ergoplatform.validation.{ValidationRules, SigmaValidationSettings} import sigmastate.AvlTreeData import sigmastate.eval._ -import sigmastate.interpreter.{ContextExtension, CryptoConstants} +import sigmastate.interpreter.{ContextExtension, CryptoConstants, Interpreter} import sigmastate.serialization.{SigmaSerializer, GroupElementSerializer} import special.collection.Coll import special.sigma.{Box, PreHeader, Header} @@ -43,8 +43,10 @@ object ErgoLikeContextTesting { self: ErgoBox, extension: ContextExtension = ContextExtension.empty, vs: SigmaValidationSettings = ValidationRules.currentSettings): ErgoLikeContext = - new ErgoLikeContext(lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), noBoxes, - boxesToSpend, spendingTransaction, boxesToSpend.indexOf(self), extension, vs, ScriptCostLimit.value, 0L) + new ErgoLikeContext( + lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), noBoxes, + boxesToSpend, spendingTransaction, boxesToSpend.indexOf(self), extension, vs, + ScriptCostLimit.value, initCost = 0L, Interpreter.MaxSupportedScriptVersion) def apply(currentHeight: Height, lastBlockUtxoRoot: AvlTreeData, @@ -53,8 +55,11 @@ object ErgoLikeContextTesting { boxesToSpend: IndexedSeq[ErgoBox], spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], selfIndex: Int) = - new ErgoLikeContext(lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), - dataBoxes, boxesToSpend, spendingTransaction, selfIndex, ContextExtension.empty, ValidationRules.currentSettings, ScriptCostLimit.value, 0L) + new ErgoLikeContext( + lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), + dataBoxes, boxesToSpend, spendingTransaction, selfIndex, ContextExtension.empty, + ValidationRules.currentSettings, ScriptCostLimit.value, + initCost = 0L, Interpreter.MaxSupportedScriptVersion) def dummy(selfDesc: ErgoBox): ErgoLikeContext = ErgoLikeContextTesting(currentHeight = 0, diff --git a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 9623b8371f..bfa056d539 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -19,7 +19,7 @@ import sigmastate.basics.ProveDHTuple import sigmastate.eval.Extensions._ import sigmastate.eval.{CostingBox, SigmaDsl, _} import sigmastate.interpreter.CryptoConstants.EcPointType -import sigmastate.interpreter.{ProverResult, ContextExtension, CryptoConstants} +import sigmastate.interpreter.{ProverResult, ContextExtension, CryptoConstants, Interpreter} import sigmastate.lang.TransformingSigmaBuilder._ import sigmastate._ import sigmastate.utxo._ @@ -30,7 +30,10 @@ import scala.collection.JavaConverters._ import scala.collection.mutable.ListBuffer import scala.reflect.ClassTag -trait ObjectGenerators extends TypeGenerators with ValidationSpecification with ConcreteCollectionGenerators { +trait ObjectGenerators extends TypeGenerators + with ValidationSpecification + with ConcreteCollectionGenerators + with TestsBase { val ThresholdLimit = 10 @@ -786,7 +789,8 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with extension = extension, validationSettings = ValidationRules.currentSettings, costLimit = costLimit, - initCost = initCost + initCost = initCost, + ActivatedVersionInTest ) } diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala index cbde55ad69..377ecbca4e 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala @@ -246,7 +246,8 @@ class SigmaDslTesting extends PropSpec new ErgoLikeContext( treeData, ctx.headers, ctx.preHeader, dataBoxes, boxesToSpend, tx, selfIndex, - extension, validationSettings, costLimit, initCost) + extension, validationSettings, costLimit, initCost, + ActivatedVersionInTest) } /** Executes the default feature verification wrapper script. diff --git a/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala b/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala index cd0be01249..c77e8605b1 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala @@ -121,5 +121,6 @@ trait SigmaTestingData extends SigmaTestingCommons with SigmaTypeGens { selfIndex = 0, headers = headers, preHeader = preHeader, dataBoxes = IndexedSeq(dataBox), extension = ContextExtension(Map(2.toByte -> IntConstant(10))), validationSettings = ValidationRules.currentSettings, - costLimit = ScriptCostLimit.value, initCost = 0L) + costLimit = ScriptCostLimit.value, initCost = 0L, + activatedScriptVersion = ActivatedVersionInTest) } From 4f264773fd6b0415970fe3e90f458957aad3c372 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 14 Dec 2020 13:33:49 +0300 Subject: [PATCH 15/31] towards-v4.0: remove Nullable from SigmaByteReader.versionContext --- .../sigmastate/interpreter/InterpreterContext.scala | 5 ++--- .../sigmastate/serialization/SigmaSerializer.scala | 10 +++++----- .../main/scala/sigmastate/utils/SigmaByteReader.scala | 9 ++++----- .../org/ergoplatform/ErgoLikeTransactionSpec.scala | 7 +++---- .../serialization/BlockSerializerSpecification.scala | 6 +++--- .../serialization/DeserializationResilience.scala | 7 +++++-- .../ErgoTreeSerializerSpecification.scala | 6 +++--- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index ab414a78e3..ab80178aaf 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -1,7 +1,6 @@ package sigmastate.interpreter import org.ergoplatform.validation.SigmaValidationSettings -import scalan.Nullable import sigmastate.SType import sigmastate.Values.EvaluatedValue import sigmastate.serialization.SigmaSerializer @@ -37,8 +36,8 @@ object ContextExtension { override def parse(r: SigmaByteReader): ContextExtension = { val extSize = r.versionContext match { - case Nullable(_) => r.getUByte() // v4.0 and above - case _ => r.getByte() // v3.x + case VersionContext(0) => r.getByte() // v3.x + case _ => r.getUByte() // v4.0 and above } val ext = (0 until extSize) .map(_ => (r.getByte(), r.getValue().asInstanceOf[EvaluatedValue[_ <: SType]])) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala index 93eb000803..8131988ee1 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala @@ -4,7 +4,6 @@ import java.nio.ByteBuffer import org.ergoplatform.SigmaConstants import org.ergoplatform.validation.SigmaValidationSettings -import scalan.Nullable import scorex.util.ByteArrayBuilder import sigmastate.lang.exceptions.SerializerException import sigmastate.utils._ @@ -30,15 +29,15 @@ object SigmaSerializer { */ def startReader(bytes: Array[Byte], pos: Int = 0, - versionContext: Nullable[VersionContext] = Nullable.None): SigmaByteReader = { + versionContext: VersionContext = VersionContext(0)): SigmaByteReader = { val buf = ByteBuffer.wrap(bytes) buf.position(pos) val r = new SigmaByteReader( new VLQByteBufferReader(buf), new ConstantStore(), resolvePlaceholdersToConstants = false, - maxTreeDepth = MaxTreeDepth, - versionContext = versionContext + versionContext = versionContext, + maxTreeDepth = MaxTreeDepth ).mark() r } @@ -47,7 +46,7 @@ object SigmaSerializer { def startReader(bytes: Array[Byte], constantStore: ConstantStore, resolvePlaceholdersToConstants: Boolean, - versionContext: Nullable[VersionContext]) + versionContext: VersionContext) (implicit vs: SigmaValidationSettings): SigmaByteReader = { val buf = ByteBuffer.wrap(bytes) val r = new SigmaByteReader(new VLQByteBufferReader(buf), @@ -94,6 +93,7 @@ abstract class SigmaSerializer[TFamily, T <: TFamily] extends Serializer[TFamily val sigmaByteReader = new SigmaByteReader(r, new ConstantStore(), resolvePlaceholdersToConstants = false, + versionContext = VersionContext(0), maxTreeDepth = SigmaSerializer.MaxTreeDepth) parse(sigmaByteReader) } diff --git a/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala index 1ce6729964..1363ed26df 100644 --- a/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala +++ b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala @@ -1,6 +1,5 @@ package sigmastate.utils -import scalan.Nullable import scorex.util.serialization.Reader import sigmastate.SType import sigmastate.Values.{SValue, Value} @@ -19,17 +18,17 @@ import spire.syntax.all.cfor * [[sigmastate.Values.ConstantPlaceholder]] * @param resolvePlaceholdersToConstants if true then resolved constants will be * substituted in the tree instead of the placeholder. - * @param maxTreeDepth limit on the tree depth (recursive invocations) - * of the deserializer * @param versionContext optional version context to support soft and * hard forks in serialization logic. * If None, then no SF or HF activated. + * @param maxTreeDepth limit on the tree depth (recursive invocations) + * of the deserializer */ class SigmaByteReader(val r: Reader, var constantStore: ConstantStore, var resolvePlaceholdersToConstants: Boolean, - val maxTreeDepth: Int = SigmaSerializer.MaxTreeDepth, - val versionContext: Nullable[VersionContext] = Nullable.None) + val versionContext: VersionContext, + val maxTreeDepth: Int = SigmaSerializer.MaxTreeDepth) extends Reader { @inline private def checkPositionLimit(): Unit = diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala index 432e0d01df..feeb674c51 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala @@ -2,7 +2,6 @@ package org.ergoplatform import org.ergoplatform.ErgoBox.TokenId import org.ergoplatform.settings.ErgoAlgos -import scalan.Nullable import scorex.crypto.hash.Digest32 import scorex.util.{Random, ModifierId} import sigmastate.SCollection.SByteArray @@ -279,7 +278,7 @@ class ErgoLikeTransactionSpec extends SigmaDslTesting { val wrongInput = Input(tx.inputs.head.boxId, ProverResult(Array.emptyByteArray, ce)) val ins = IndexedSeq(wrongInput) ++ tx.inputs.tail val tx2 = copyTransaction(tx)(inputs = ins) - def roundtrip(version: Nullable[VersionContext]) = { + def roundtrip(version: VersionContext) = { val bs = ErgoLikeTransactionSerializer.toBytes(tx2) val restored = ErgoLikeTransactionSerializer.parse( SigmaSerializer.startReader(bs, 0, version) @@ -288,11 +287,11 @@ class ErgoLikeTransactionSpec extends SigmaDslTesting { } // successful for v4.0 and above - roundtrip(Nullable(VersionContext.MaxSupportedVersion)) + roundtrip(VersionContext.MaxSupportedVersion) // unsuccessful if version context is not passed (which means v3.x version) assertExceptionThrown( - roundtrip(Nullable.None), + roundtrip(VersionContext(0)), { _ => true } ) } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala index 9ac361db1a..45766887e7 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala @@ -1,10 +1,10 @@ package sigmastate.serialization import org.scalacheck.Gen -import scalan.Nullable import sigmastate.SType import sigmastate.Values.Constant -import sigmastate.lang.{DeserializationSigmaBuilder, SigmaBuilder} +import sigmastate.interpreter.VersionContext +import sigmastate.lang.{SigmaBuilder, DeserializationSigmaBuilder} class BlockSerializerSpecification extends SerializationSpecification { @@ -28,7 +28,7 @@ class BlockSerializerSpecification extends SerializationSpecification { val s = ConstantPlaceholderSerializer(DeserializationSigmaBuilder.mkConstantPlaceholder) val w = SigmaSerializer.startWriter() s.serialize(placeholder, w) - val r = SigmaSerializer.startReader(w.toBytes, store, resolvePlaceholdersToConstants = false, Nullable.None) + val r = SigmaSerializer.startReader(w.toBytes, store, resolvePlaceholdersToConstants = false, VersionContext(0)) s.parse(r) shouldEqual placeholder } } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala index 7d0f9aaf9f..06381c7a69 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala @@ -3,7 +3,7 @@ package sigmastate.serialization import java.nio.ByteBuffer import org.ergoplatform.validation.ValidationException -import org.ergoplatform.{ErgoBoxCandidate, ErgoLikeContext, Outputs} +import org.ergoplatform.{ErgoBoxCandidate, Outputs} import org.scalacheck.Gen import scalan.util.BenchmarkUtil import scorex.util.serialization.{Reader, VLQByteBufferReader} @@ -13,7 +13,7 @@ import sigmastate.eval.Extensions._ import sigmastate.eval._ import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} -import sigmastate.interpreter.{ContextExtension, CostedProverResult, CryptoConstants} +import sigmastate.interpreter.{ContextExtension, CryptoConstants, CostedProverResult, VersionContext} import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.{DeserializeCallDepthExceeded, InputSizeLimitExceeded, InvalidTypePrefix, SerializerException} import sigmastate.serialization.OpCodes._ @@ -37,6 +37,7 @@ class DeserializationResilience extends SerializationSpecification with SigmaTes new VLQByteBufferReader(buf), new ConstantStore(), resolvePlaceholdersToConstants = false, + VersionContext(0), maxTreeDepth = maxTreeDepth).mark() r } @@ -106,6 +107,7 @@ class DeserializationResilience extends SerializationSpecification with SigmaTes SigmaByteReader(r, new ConstantStore(), resolvePlaceholdersToConstants = false, + VersionContext(0), maxTreeDepth = SigmaSerializer.MaxTreeDepth) { val levels: mutable.ArrayBuilder[Int] = mutable.ArrayBuilder.make[Int]() override def level_=(v: Int): Unit = { @@ -126,6 +128,7 @@ class DeserializationResilience extends SerializationSpecification with SigmaTes SigmaByteReader(r, new ConstantStore(), resolvePlaceholdersToConstants = false, + VersionContext(0), maxTreeDepth = SigmaSerializer.MaxTreeDepth) { private var levelCall: Int = 0 override def level_=(v: Int): Unit = { diff --git a/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala index 55ac192c24..00e569f66c 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala @@ -2,11 +2,11 @@ package sigmastate.serialization import java.math.BigInteger -import scalan.Nullable -import sigmastate.Values.{ShortConstant, LongConstant, BigIntConstant, SigmaPropValue, IntConstant, ErgoTree, ByteConstant} +import sigmastate.Values.{ShortConstant, BigIntConstant, SigmaPropValue, IntConstant, ErgoTree, ByteConstant} import sigmastate._ import sigmastate.eval.{IRContext, CBigInt} import sigmastate.helpers.SigmaTestingCommons +import sigmastate.interpreter.VersionContext import sigmastate.lang.exceptions.{SerializerException, InputSizeLimitExceeded} import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer @@ -46,7 +46,7 @@ class ErgoTreeSerializerSpecification extends SerializationSpecification treeBytes, new ConstantStore(deserializedConstants), resolvePlaceholdersToConstants = true, - versionContext = Nullable.None) + versionContext = VersionContext(0)) val deserializedTree = ValueSerializer.deserialize(r) deserializedTree shouldEqual tree } From efb010b143c181e35d97bf060383e0f6a56fc48b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 14 Dec 2020 14:28:35 +0300 Subject: [PATCH 16/31] towards-v4.0: introduce CrossVersionProps for tests --- .../scala/sigmastate/CrossVersionProps.scala | 35 +++++++++++++++++++ .../BlockSerializerSpecification.scala | 7 ++-- .../DeserializationResilience.scala | 12 ++++--- .../ErgoTreeSerializerSpecification.scala | 6 ++-- 4 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala diff --git a/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala b/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala new file mode 100644 index 0000000000..670102fb1d --- /dev/null +++ b/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala @@ -0,0 +1,35 @@ +package sigmastate + +import scala.util.DynamicVariable +import sigmastate.interpreter.{Interpreter, VersionContext} +import org.scalatest.{PropSpecLike, Tag} +import org.scalactic.source.Position + +trait CrossVersionProps extends PropSpecLike { + + val versionContextsToTest: Seq[VersionContext] = + (0 to Interpreter.MaxSupportedScriptVersion) + .map(i => VersionContext(i.toByte)).toArray[VersionContext] + + private val _activatedVersion = new DynamicVariable[VersionContext](VersionContext(0)) + + def activatedVersion: VersionContext = _activatedVersion.value + + override protected def property(testName: String, testTags: Tag*) + (testFun: => Any) + (implicit pos: Position): Unit = { + + super.property(testName, testTags:_*) { + versionContextsToTest.foreach { vc => + _activatedVersion.withValue(vc) { + try testFun + catch { + case t: Throwable => + println(s"activatedVersion = $vc") + throw t + } + } + } + } + } +} diff --git a/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala index 45766887e7..b06bc7a7f4 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala @@ -1,12 +1,11 @@ package sigmastate.serialization import org.scalacheck.Gen -import sigmastate.SType +import sigmastate.{SType, CrossVersionProps} import sigmastate.Values.Constant -import sigmastate.interpreter.VersionContext import sigmastate.lang.{SigmaBuilder, DeserializationSigmaBuilder} -class BlockSerializerSpecification extends SerializationSpecification { +class BlockSerializerSpecification extends SerializationSpecification with CrossVersionProps { property("ValDef: serializer round trip") { forAll(valOrFunDefGen) { v => @@ -28,7 +27,7 @@ class BlockSerializerSpecification extends SerializationSpecification { val s = ConstantPlaceholderSerializer(DeserializationSigmaBuilder.mkConstantPlaceholder) val w = SigmaSerializer.startWriter() s.serialize(placeholder, w) - val r = SigmaSerializer.startReader(w.toBytes, store, resolvePlaceholdersToConstants = false, VersionContext(0)) + val r = SigmaSerializer.startReader(w.toBytes, store, resolvePlaceholdersToConstants = false, activatedVersion) s.parse(r) shouldEqual placeholder } } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala index 06381c7a69..a0e0f1245b 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala @@ -13,7 +13,7 @@ import sigmastate.eval.Extensions._ import sigmastate.eval._ import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} -import sigmastate.interpreter.{ContextExtension, CryptoConstants, CostedProverResult, VersionContext} +import sigmastate.interpreter.{ContextExtension, CryptoConstants, CostedProverResult} import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.{DeserializeCallDepthExceeded, InputSizeLimitExceeded, InvalidTypePrefix, SerializerException} import sigmastate.serialization.OpCodes._ @@ -23,7 +23,9 @@ import sigmastate.utils.Helpers._ import scala.collection.mutable -class DeserializationResilience extends SerializationSpecification with SigmaTestingCommons { +class DeserializationResilience extends SerializationSpecification + with SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR: TestingIRContext = new TestingIRContext { // substFromCostTable = false @@ -37,7 +39,7 @@ class DeserializationResilience extends SerializationSpecification with SigmaTes new VLQByteBufferReader(buf), new ConstantStore(), resolvePlaceholdersToConstants = false, - VersionContext(0), + activatedVersion, maxTreeDepth = maxTreeDepth).mark() r } @@ -107,7 +109,7 @@ class DeserializationResilience extends SerializationSpecification with SigmaTes SigmaByteReader(r, new ConstantStore(), resolvePlaceholdersToConstants = false, - VersionContext(0), + activatedVersion, maxTreeDepth = SigmaSerializer.MaxTreeDepth) { val levels: mutable.ArrayBuilder[Int] = mutable.ArrayBuilder.make[Int]() override def level_=(v: Int): Unit = { @@ -128,7 +130,7 @@ class DeserializationResilience extends SerializationSpecification with SigmaTes SigmaByteReader(r, new ConstantStore(), resolvePlaceholdersToConstants = false, - VersionContext(0), + activatedVersion, maxTreeDepth = SigmaSerializer.MaxTreeDepth) { private var levelCall: Int = 0 override def level_=(v: Int): Unit = { diff --git a/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala index 00e569f66c..4d358930a6 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala @@ -6,12 +6,12 @@ import sigmastate.Values.{ShortConstant, BigIntConstant, SigmaPropValue, IntCons import sigmastate._ import sigmastate.eval.{IRContext, CBigInt} import sigmastate.helpers.SigmaTestingCommons -import sigmastate.interpreter.VersionContext import sigmastate.lang.exceptions.{SerializerException, InputSizeLimitExceeded} import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer class ErgoTreeSerializerSpecification extends SerializationSpecification - with SigmaTestingCommons { + with SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR: TestingIRContext = new TestingIRContext { beginPass(noConstPropagationPass) @@ -46,7 +46,7 @@ class ErgoTreeSerializerSpecification extends SerializationSpecification treeBytes, new ConstantStore(deserializedConstants), resolvePlaceholdersToConstants = true, - versionContext = VersionContext(0)) + versionContext = activatedVersion) val deserializedTree = ValueSerializer.deserialize(r) deserializedTree shouldEqual tree } From e6559a8edfdfdb1fd162bd737764fec27714ef34 Mon Sep 17 00:00:00 2001 From: Alex Chepurnoy Date: Wed, 16 Dec 2020 12:48:44 +0300 Subject: [PATCH 17/31] CE deserialization fix --- .../interpreter/InterpreterContext.scala | 8 ++-- .../ErgoLikeTransactionSpec.scala | 46 ++++++++++--------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index ab80178aaf..0def02a259 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -35,16 +35,16 @@ object ContextExtension { } override def parse(r: SigmaByteReader): ContextExtension = { - val extSize = r.versionContext match { - case VersionContext(0) => r.getByte() // v3.x - case _ => r.getUByte() // v4.0 and above - } + val extSize = r.getByte() + if (extSize < 0) throw new Exception("Negative amount of context extension values") val ext = (0 until extSize) .map(_ => (r.getByte(), r.getValue().asInstanceOf[EvaluatedValue[_ <: SType]])) .toMap[Byte, EvaluatedValue[_ <: SType]] ContextExtension(ext) } + } + } diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala index feeb674c51..8982be65dc 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala @@ -272,28 +272,32 @@ class ErgoLikeTransactionSpec extends SigmaDslTesting { } property("context extension serialization") { - forAll { tx: ErgoLikeTransaction => - val idRange = Byte.MinValue to (Byte.MaxValue - 1) - val ce = ContextExtension(idRange.map(id => id.toByte -> IntConstant(4)).toMap) - val wrongInput = Input(tx.inputs.head.boxId, ProverResult(Array.emptyByteArray, ce)) - val ins = IndexedSeq(wrongInput) ++ tx.inputs.tail - val tx2 = copyTransaction(tx)(inputs = ins) - def roundtrip(version: VersionContext) = { - val bs = ErgoLikeTransactionSerializer.toBytes(tx2) - val restored = ErgoLikeTransactionSerializer.parse( - SigmaSerializer.startReader(bs, 0, version) - ) - restored.inputs.head.extension.values.size shouldBe tx2.inputs.head.extension.values.size - } - - // successful for v4.0 and above - roundtrip(VersionContext.MaxSupportedVersion) + forAll { (tx: ErgoLikeTransaction, startIndex: Byte, endIndex: Byte) => + whenever(endIndex >= startIndex) { + val idRange = endIndex - startIndex + + val ce = ContextExtension(startIndex.to(endIndex).map(id => id.toByte -> IntConstant(4)).toMap) + val wrongInput = Input(tx.inputs.head.boxId, ProverResult(Array.emptyByteArray, ce)) + val ins = IndexedSeq(wrongInput) ++ tx.inputs.tail + val tx2 = copyTransaction(tx)(inputs = ins) + + def roundtrip() = { + val bs = ErgoLikeTransactionSerializer.toBytes(tx2) + val restored = ErgoLikeTransactionSerializer.parse( + SigmaSerializer.startReader(bs, 0) + ) + restored.inputs.head.extension.values.size shouldBe tx2.inputs.head.extension.values.size + } - // unsuccessful if version context is not passed (which means v3.x version) - assertExceptionThrown( - roundtrip(VersionContext(0)), - { _ => true } - ) + if(idRange < 127) { + roundtrip() + } else { + assertExceptionThrown( + roundtrip(), + { _ => true } + ) + } + } } } } From 367d8cf03a2c133914458ed5818ddd9c8c2f5fb8 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 16 Dec 2020 15:04:00 +0300 Subject: [PATCH 18/31] towards-v4.0: check size in ContextExtension serializer --- .../scala/sigmastate/interpreter/InterpreterContext.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index 0def02a259..be12e8ef98 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -30,13 +30,17 @@ object ContextExtension { object serializer extends SigmaSerializer[ContextExtension, ContextExtension] { override def serialize(obj: ContextExtension, w: SigmaByteWriter): Unit = { - w.putUByte(obj.values.size) + val size = obj.values.size + if (size > Byte.MaxValue) + error(s"Number of ContextExtension values $size exceeds ${Byte.MaxValue}.") + w.putUByte(size) obj.values.foreach { case (id, v) => w.put(id).putValue(v) } } override def parse(r: SigmaByteReader): ContextExtension = { val extSize = r.getByte() - if (extSize < 0) throw new Exception("Negative amount of context extension values") + if (extSize < 0) + error(s"Negative amount of context extension values: $extSize") val ext = (0 until extSize) .map(_ => (r.getByte(), r.getValue().asInstanceOf[EvaluatedValue[_ <: SType]])) .toMap[Byte, EvaluatedValue[_ <: SType]] From e39cdba3b49a02dc17de97f18f22f3d4a956b9b1 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 16 Dec 2020 15:14:22 +0300 Subject: [PATCH 19/31] towards-v4.0: removed VersionContext --- .../interpreter/InterpreterContext.scala | 11 ------ .../serialization/SigmaSerializer.scala | 12 ++----- .../sigmastate/utils/SigmaByteReader.scala | 5 --- .../ErgoLikeTransactionSpec.scala | 2 +- .../scala/sigmastate/CrossVersionProps.scala | 35 ------------------- .../BlockSerializerSpecification.scala | 6 ++-- .../DeserializationResilience.scala | 6 +--- .../ErgoTreeSerializerSpecification.scala | 6 ++-- 8 files changed, 10 insertions(+), 73 deletions(-) delete mode 100644 sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index be12e8ef98..058aa0615a 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -109,14 +109,3 @@ trait InterpreterContext { def toSigmaContext(isCost: Boolean, extensions: Map[Byte, AnyValue] = Map()): sigma.Context } -/** Descriptor of protocol versions. - * @param scriptVersion the version of ErgoTree (see ErgoTree.header) - */ -case class VersionContext(scriptVersion: Byte) - -object VersionContext { - - /** Descriptor of the max supported versions. */ - val MaxSupportedVersion = VersionContext( - scriptVersion = Interpreter.MaxSupportedScriptVersion) -} diff --git a/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala index 8131988ee1..5ec895d7b5 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala @@ -8,7 +8,6 @@ import scorex.util.ByteArrayBuilder import sigmastate.lang.exceptions.SerializerException import sigmastate.utils._ import scorex.util.serialization._ -import sigmastate.interpreter.VersionContext import sigmastate.serialization.OpCodes.OpCode object SigmaSerializer { @@ -28,15 +27,13 @@ object SigmaSerializer { * obj -> r.consumed */ def startReader(bytes: Array[Byte], - pos: Int = 0, - versionContext: VersionContext = VersionContext(0)): SigmaByteReader = { + pos: Int = 0): SigmaByteReader = { val buf = ByteBuffer.wrap(bytes) buf.position(pos) val r = new SigmaByteReader( new VLQByteBufferReader(buf), new ConstantStore(), resolvePlaceholdersToConstants = false, - versionContext = versionContext, maxTreeDepth = MaxTreeDepth ).mark() r @@ -45,15 +42,13 @@ object SigmaSerializer { /** Helper function to be use in serializers. */ def startReader(bytes: Array[Byte], constantStore: ConstantStore, - resolvePlaceholdersToConstants: Boolean, - versionContext: VersionContext) + resolvePlaceholdersToConstants: Boolean) (implicit vs: SigmaValidationSettings): SigmaByteReader = { val buf = ByteBuffer.wrap(bytes) val r = new SigmaByteReader(new VLQByteBufferReader(buf), constantStore, resolvePlaceholdersToConstants, - maxTreeDepth = MaxTreeDepth, - versionContext = versionContext).mark() + maxTreeDepth = MaxTreeDepth).mark() r } @@ -93,7 +88,6 @@ abstract class SigmaSerializer[TFamily, T <: TFamily] extends Serializer[TFamily val sigmaByteReader = new SigmaByteReader(r, new ConstantStore(), resolvePlaceholdersToConstants = false, - versionContext = VersionContext(0), maxTreeDepth = SigmaSerializer.MaxTreeDepth) parse(sigmaByteReader) } diff --git a/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala index 1363ed26df..c736dc1d0a 100644 --- a/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala +++ b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteReader.scala @@ -6,7 +6,6 @@ import sigmastate.Values.{SValue, Value} import sigmastate.lang.exceptions.{InputSizeLimitExceeded, DeserializeCallDepthExceeded} import sigmastate.serialization._ import scorex.util.Extensions._ -import sigmastate.interpreter.VersionContext import spire.syntax.all.cfor /** Reader used in the concrete implementations of [[SigmaSerializer]]. @@ -18,16 +17,12 @@ import spire.syntax.all.cfor * [[sigmastate.Values.ConstantPlaceholder]] * @param resolvePlaceholdersToConstants if true then resolved constants will be * substituted in the tree instead of the placeholder. - * @param versionContext optional version context to support soft and - * hard forks in serialization logic. - * If None, then no SF or HF activated. * @param maxTreeDepth limit on the tree depth (recursive invocations) * of the deserializer */ class SigmaByteReader(val r: Reader, var constantStore: ConstantStore, var resolvePlaceholdersToConstants: Boolean, - val versionContext: VersionContext, val maxTreeDepth: Int = SigmaSerializer.MaxTreeDepth) extends Reader { diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala index 8982be65dc..66b942b531 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala @@ -7,7 +7,7 @@ import scorex.util.{Random, ModifierId} import sigmastate.SCollection.SByteArray import sigmastate.{SSigmaProp, SPair, SInt, TrivialProp, SType} import sigmastate.Values.{LongConstant, FalseLeaf, ConstantNode, SigmaPropConstant, ConstantPlaceholder, TrueSigmaProp, ByteArrayConstant, IntConstant, ErgoTree} -import sigmastate.interpreter.{ProverResult, ContextExtension, VersionContext} +import sigmastate.interpreter.{ProverResult, ContextExtension} import sigmastate.serialization.SigmaSerializer import sigmastate.eval._ import sigmastate.eval.Extensions._ diff --git a/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala b/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala deleted file mode 100644 index 670102fb1d..0000000000 --- a/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala +++ /dev/null @@ -1,35 +0,0 @@ -package sigmastate - -import scala.util.DynamicVariable -import sigmastate.interpreter.{Interpreter, VersionContext} -import org.scalatest.{PropSpecLike, Tag} -import org.scalactic.source.Position - -trait CrossVersionProps extends PropSpecLike { - - val versionContextsToTest: Seq[VersionContext] = - (0 to Interpreter.MaxSupportedScriptVersion) - .map(i => VersionContext(i.toByte)).toArray[VersionContext] - - private val _activatedVersion = new DynamicVariable[VersionContext](VersionContext(0)) - - def activatedVersion: VersionContext = _activatedVersion.value - - override protected def property(testName: String, testTags: Tag*) - (testFun: => Any) - (implicit pos: Position): Unit = { - - super.property(testName, testTags:_*) { - versionContextsToTest.foreach { vc => - _activatedVersion.withValue(vc) { - try testFun - catch { - case t: Throwable => - println(s"activatedVersion = $vc") - throw t - } - } - } - } - } -} diff --git a/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala index b06bc7a7f4..c07081b816 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/BlockSerializerSpecification.scala @@ -1,11 +1,11 @@ package sigmastate.serialization import org.scalacheck.Gen -import sigmastate.{SType, CrossVersionProps} +import sigmastate.SType import sigmastate.Values.Constant import sigmastate.lang.{SigmaBuilder, DeserializationSigmaBuilder} -class BlockSerializerSpecification extends SerializationSpecification with CrossVersionProps { +class BlockSerializerSpecification extends SerializationSpecification { property("ValDef: serializer round trip") { forAll(valOrFunDefGen) { v => @@ -27,7 +27,7 @@ class BlockSerializerSpecification extends SerializationSpecification with Cross val s = ConstantPlaceholderSerializer(DeserializationSigmaBuilder.mkConstantPlaceholder) val w = SigmaSerializer.startWriter() s.serialize(placeholder, w) - val r = SigmaSerializer.startReader(w.toBytes, store, resolvePlaceholdersToConstants = false, activatedVersion) + val r = SigmaSerializer.startReader(w.toBytes, store, resolvePlaceholdersToConstants = false) s.parse(r) shouldEqual placeholder } } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala index a0e0f1245b..2b56a8372a 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala @@ -24,8 +24,7 @@ import sigmastate.utils.Helpers._ import scala.collection.mutable class DeserializationResilience extends SerializationSpecification - with SigmaTestingCommons - with CrossVersionProps { + with SigmaTestingCommons { implicit lazy val IR: TestingIRContext = new TestingIRContext { // substFromCostTable = false @@ -39,7 +38,6 @@ class DeserializationResilience extends SerializationSpecification new VLQByteBufferReader(buf), new ConstantStore(), resolvePlaceholdersToConstants = false, - activatedVersion, maxTreeDepth = maxTreeDepth).mark() r } @@ -109,7 +107,6 @@ class DeserializationResilience extends SerializationSpecification SigmaByteReader(r, new ConstantStore(), resolvePlaceholdersToConstants = false, - activatedVersion, maxTreeDepth = SigmaSerializer.MaxTreeDepth) { val levels: mutable.ArrayBuilder[Int] = mutable.ArrayBuilder.make[Int]() override def level_=(v: Int): Unit = { @@ -130,7 +127,6 @@ class DeserializationResilience extends SerializationSpecification SigmaByteReader(r, new ConstantStore(), resolvePlaceholdersToConstants = false, - activatedVersion, maxTreeDepth = SigmaSerializer.MaxTreeDepth) { private var levelCall: Int = 0 override def level_=(v: Int): Unit = { diff --git a/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala index 4d358930a6..4dd1cb21d4 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala @@ -10,8 +10,7 @@ import sigmastate.lang.exceptions.{SerializerException, InputSizeLimitExceeded} import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer class ErgoTreeSerializerSpecification extends SerializationSpecification - with SigmaTestingCommons - with CrossVersionProps { + with SigmaTestingCommons { implicit lazy val IR: TestingIRContext = new TestingIRContext { beginPass(noConstPropagationPass) @@ -45,8 +44,7 @@ class ErgoTreeSerializerSpecification extends SerializationSpecification val r = SigmaSerializer.startReader( treeBytes, new ConstantStore(deserializedConstants), - resolvePlaceholdersToConstants = true, - versionContext = activatedVersion) + resolvePlaceholdersToConstants = true) val deserializedTree = ValueSerializer.deserialize(r) deserializedTree shouldEqual tree } From 83565d814f449cb6a5d59ab80b88aa0ffdeb5b12 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 16 Dec 2020 15:25:35 +0300 Subject: [PATCH 20/31] towards-v4.0: fixes from review --- .../src/main/scala/org/ergoplatform/JsonCodecs.scala | 4 ++-- sigmastate/src/main/scala/sigmastate/Values.scala | 7 ++++++- .../scala/sigmastate/serialization/SigmaSerializer.scala | 3 --- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala b/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala index 44997fb171..28a905d342 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/JsonCodecs.scala @@ -401,7 +401,7 @@ trait JsonCodecs { "validationSettings" -> ctx.validationSettings.asJson, "costLimit" -> ctx.costLimit.asJson, "initCost" -> ctx.initCost.asJson, - "activatedVersion" -> ctx.activatedScriptVersion.asJson + "scriptVersion" -> ctx.activatedScriptVersion.asJson ) }) @@ -418,7 +418,7 @@ trait JsonCodecs { validationSettings <- cursor.downField("validationSettings").as[SigmaValidationSettings] costLimit <- cursor.downField("costLimit").as[Long] initCost <- cursor.downField("initCost").as[Long] - version <- cursor.downField("activatedVersion").as[Byte] + version <- cursor.downField("scriptVersion").as[Byte] } yield new ErgoLikeContext( lastBlockUtxoRoot, Colls.fromArray(headers.toArray), preHeader, dataBoxes, boxesToSpend, spendingTransaction, selfIndex, extension, diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index 71f4b5f014..d7416b8e18 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -1058,10 +1058,15 @@ object Values { (header | version).toByte } + /** Creates valid header byte with the given version. + * The SizeFlag is set if version > 0 */ @inline def headerWithVersion(version: Byte): Byte = { + // take default header and embedd the given version in it var h = updateVersionBits(DefaultHeader, version) - if (version > 0) + if (version > 0) { + // set SizeFlag if version is greater then 0 (see require() in ErgoTree constructor) h = (h | ErgoTree.SizeFlag).toByte + } h } diff --git a/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala index 5ec895d7b5..c486cf34bb 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/SigmaSerializer.scala @@ -17,9 +17,6 @@ object SigmaSerializer { val MaxPropositionSize: Int = SigmaConstants.MaxPropositionBytes.value val MaxTreeDepth: Int = SigmaConstants.MaxTreeDepth.value - //TODO v5.0: remove default value of versionContext parameter - // All usages of this method should pass a version context explicitly. - /** Helper function to be use in serializers. * Starting position is marked and then used to compute number of consumed bytes. * val r = Serializer.startReader(bytes, pos) From b7e1420c3f047c0ab37944110b2aa82c7eca6dad Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 17 Dec 2020 21:32:45 +0300 Subject: [PATCH 21/31] towards-v4.0: check activatedScriptVersion in verify only --- .../sigmastate/interpreter/Interpreter.scala | 43 +++++++++---------- .../ScriptVersionSwitchSpecification.scala | 25 +++++------ 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index e283acb10d..e50729635a 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -22,7 +22,7 @@ import org.ergoplatform.validation.ValidationRules._ import scalan.util.BenchmarkUtil import sigmastate.utils.Helpers._ -import scala.util.Try +import scala.util.{Try, Success} trait Interpreter extends ScorexLogging { @@ -195,27 +195,6 @@ trait Interpreter extends ScorexLogging { def fullReduction(ergoTree: ErgoTree, context: CTX, env: ScriptEnv): (SigmaBoolean, Long) = { - // TODO v5.0: the condition below should be revised if necessary - // The following conditions define behavior which depend on the version of ergoTree - // This works in addition to more fine-grained soft-forkabiltiy mechanism implemented - // using ValidationRules (see trySoftForkable method call here and in reduceToCrypto). - if (context.activatedScriptVersion > Interpreter.MaxSupportedScriptVersion) { - // > 90% has already switched to higher version, accept without verification - // NOTE: this path should never be taken for validation of candidate blocks - // in which case Ergo node should always pass Interpreter.MaxSupportedScriptVersion - // as the value of ErgoLikeContext.activatedScriptVersion. - // see also ErgoLikeContext ScalaDoc. - return TrivialProp.TrueProp -> context.initCost - } else { - // activated version is within the supported range [0..MaxSupportedScriptVersion] - // however - if (ergoTree.version > context.activatedScriptVersion) { - throw new InterpreterException( - s"ErgoTree version ${ergoTree.version} is higher than activated ${context.activatedScriptVersion}") - } - // else proceed normally - } - implicit val vs: SigmaValidationSettings = context.validationSettings val initCost = JMath.addExact(ergoTree.complexity.toLong, context.initCost) @@ -261,6 +240,26 @@ trait Interpreter extends ScorexLogging { proof: Array[Byte], message: Array[Byte]): Try[VerificationResult] = { val (res, t) = BenchmarkUtil.measureTime(Try { + // TODO v5.0: the condition below should be revised if necessary + // The following conditions define behavior which depend on the version of ergoTree + // This works in addition to more fine-grained soft-forkabiltiy mechanism implemented + // using ValidationRules (see trySoftForkable method call here and in reduceToCrypto). + if (context.activatedScriptVersion > Interpreter.MaxSupportedScriptVersion) { + // > 90% has already switched to higher version, accept without verification + // NOTE: this path should never be taken for validation of candidate blocks + // in which case Ergo node should always pass Interpreter.MaxSupportedScriptVersion + // as the value of ErgoLikeContext.activatedScriptVersion. + // see also ErgoLikeContext ScalaDoc. + return Success(true -> context.initCost) + } else { + // activated version is within the supported range [0..MaxSupportedScriptVersion] + // however + if (ergoTree.version > context.activatedScriptVersion) { + throw new InterpreterException( + s"ErgoTree version ${ergoTree.version} is higher than activated ${context.activatedScriptVersion}") + } + // else proceed normally + } val (cProp, cost) = fullReduction(ergoTree, context, env) diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index 37e3de2943..98730eaef5 100644 --- a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -148,14 +148,10 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { val headerFlags = ErgoTree.headerWithVersion( 2 /* Script v2 */) val ergoTree = createErgoTree(headerFlags = headerFlags) - // both prove and verify are rejecting - assertExceptionThrown( - testProve(ergoTree, activatedScriptVersion = 1 /* SF Status: inactive */), - { t => - t.isInstanceOf[InterpreterException] && - t.getMessage.contains(s"ErgoTree version ${ergoTree.version} is higher than activated 1") - }) + // the prove is successful (since it is not part of consensus) + testProve(ergoTree, activatedScriptVersion = 1 /* SF Status: inactive */) + // and verify is rejecting assertExceptionThrown( testVerify(ergoTree, activatedScriptVersion = 1 /* SF Status: inactive */), { t => @@ -204,12 +200,13 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { val activatedVersion = 2.toByte // SF Status: active - // both prove and verify are accepting without evaluation - val expectedCost = 0L + // the prove is doing normal reduction and proof generation val pr = testProve(ergoTree, activatedScriptVersion = activatedVersion) pr.proof shouldBe Array.emptyByteArray - pr.cost shouldBe expectedCost + pr.cost shouldBe 5464 + // and verify is accepting without evaluation + val expectedCost = 0L val (ok, cost) = testVerify(ergoTree, activatedScriptVersion = activatedVersion) ok shouldBe true cost shouldBe expectedCost @@ -225,15 +222,15 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { val activatedVersion = 2.toByte // SF Status: active - // both prove and verify are accepting without evaluation - val expectedCost = 0L + // the prove is doing normal reduction and proof generation val pr = testProve(ergoTree, activatedScriptVersion = activatedVersion) pr.proof shouldBe Array.emptyByteArray - pr.cost shouldBe expectedCost + pr.cost shouldBe 5464 + // and verify is accepting without evaluation val (ok, cost) = testVerify(ergoTree, activatedScriptVersion = activatedVersion) ok shouldBe true - cost shouldBe expectedCost + cost shouldBe 0L } } From 5746676a123717acbf3e0790e50bd436f319055a Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 18 Dec 2020 12:42:21 +0300 Subject: [PATCH 22/31] towards-v4.0: remove changes incompatible with v3.x --- .../src/main/scala/sigmastate/interpreter/Interpreter.scala | 2 +- .../main/scala/sigmastate/interpreter/InterpreterContext.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index 7200077375..577204c7fd 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -152,7 +152,7 @@ trait Interpreter extends ScorexLogging { implicit val vs = context.validationSettings val maxCost = context.costLimit val initCost = context.initCost - trySoftForkable[ReductionResult](whenSoftFork = TrivialProp.TrueProp -> initCost) { + trySoftForkable[ReductionResult](whenSoftFork = TrivialProp.TrueProp -> 0) { val costingRes = doCostingEx(env, exp, true) val costF = costingRes.costF IR.onCostingResult(env, exp, costingRes) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala index 058aa0615a..fd9f054ca7 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/InterpreterContext.scala @@ -76,7 +76,7 @@ trait InterpreterContext { * performed via miners voting. * The maximum version supported by the interpreter is defined by * `Interpreter.MaxSupportedScriptVersion`. As a result, the execution of the - * `Interpreter.verify` and `Interpreter.prove` methods depend on the relation between + * `Interpreter.verify` method depends on the relation between * max supported and activated version. (see docs/aot-jit-switch.md). */ def activatedScriptVersion: Byte From 7677dedb89be54651efaab38d736e00743484ad1 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 18 Dec 2020 21:08:28 +0300 Subject: [PATCH 23/31] versioned-tests: dynamic variables for activatedVersion and ergoTree version --- .../sigmastate/CostingSpecification.scala | 2 +- .../scala/sigmastate/CrossVersionProps.scala | 35 +++++++++++++++++++ .../src/test/scala/sigmastate/TestsBase.scala | 13 ++++++- .../generators/ObjectGenerators.scala | 2 +- .../special/sigma/SigmaDslSpecification.scala | 2 -- .../scala/special/sigma/SigmaDslTesting.scala | 16 ++------- .../special/sigma/SigmaTestingData.scala | 4 +-- 7 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala diff --git a/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala index 9738ddf98c..3d630f471e 100644 --- a/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala @@ -69,7 +69,7 @@ class CostingSpecification extends SigmaTestingData { boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx, selfIndex = 0, extension, ValidationRules.currentSettings, ScriptCostLimit.value, - CostTable.interpreterInitCost, ActivatedVersionInTest + CostTable.interpreterInitCost, activatedVersionInTests ) def cost(script: String)(expCost: Int): Unit = { diff --git a/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala b/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala new file mode 100644 index 0000000000..7c737d3d9e --- /dev/null +++ b/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala @@ -0,0 +1,35 @@ +package sigmastate + +import org.scalatest.{PropSpecLike, Tag} +import org.scalactic.source.Position +import spire.syntax.all.cfor + +trait CrossVersionProps extends PropSpecLike with TestsBase { + + override protected def property(testName: String, testTags: Tag*) + (testFun: => Any) + (implicit pos: Position): Unit = { + + super.property(testName, testTags:_*) { + cfor(0)(_ < activatedVersions.length, _ + 1) { i => + val activatedVersion = activatedVersions(i) + _currActivatedVersion.withValue(activatedVersion) { + + cfor(0)( + i => i < ergoTreeVersions.length && ergoTreeVersions(i) <= activatedVersion, + _ + 1) { j => + val treeVersion = ergoTreeVersions(j) + _currErgoTreeVersion.withValue(treeVersion) { + try testFun + catch { + case t: Throwable => + println(s"ActivatedVersion = $activatedVersion; ErgoTree version = $treeVersion") + throw t + } + } + } + } + } + } + } +} diff --git a/sigmastate/src/test/scala/sigmastate/TestsBase.scala b/sigmastate/src/test/scala/sigmastate/TestsBase.scala index ca723717ae..5450799c02 100644 --- a/sigmastate/src/test/scala/sigmastate/TestsBase.scala +++ b/sigmastate/src/test/scala/sigmastate/TestsBase.scala @@ -2,8 +2,19 @@ package sigmastate import sigmastate.interpreter.Interpreter +import scala.util.DynamicVariable + trait TestsBase { - val ActivatedVersionInTest = Interpreter.MaxSupportedScriptVersion + val activatedVersions: Seq[Byte] = Array[Byte](0, 1) + + private[sigmastate] val _currActivatedVersion = new DynamicVariable[Byte](0) + def activatedVersionInTests: Byte = _currActivatedVersion.value + + val ergoTreeVersions: Seq[Byte] = + (0 to Interpreter.MaxSupportedScriptVersion).map(_.toByte).toArray[Byte] + + private[sigmastate] val _currErgoTreeVersion = new DynamicVariable[Byte](0) + def ergoTreeVersionInTests: Byte = _currErgoTreeVersion.value } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index bfa056d539..673a7500dd 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -790,7 +790,7 @@ trait ObjectGenerators extends TypeGenerators validationSettings = ValidationRules.currentSettings, costLimit = costLimit, initCost = initCost, - ActivatedVersionInTest + activatedScriptVersion = activatedVersionInTests ) } diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala index 6e4c20feab..cc7ce5f4b0 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala @@ -2349,8 +2349,6 @@ class SigmaDslSpecification extends SigmaDslTesting { suite => // doApply((CFunc[Int, Int](ctx, code), 10)) // } - lazy val ctx = ergoCtx.toSigmaContext(false) - property("Box properties equivalence") { val b1 = CostingBox( false, diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala index 377ecbca4e..f583e9bfc9 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala @@ -247,25 +247,15 @@ class SigmaDslTesting extends PropSpec treeData, ctx.headers, ctx.preHeader, dataBoxes, boxesToSpend, tx, selfIndex, extension, validationSettings, costLimit, initCost, - ActivatedVersionInTest) - } - - /** Executes the default feature verification wrapper script. - * @param input the given input - * @param expected the given expected results (values and costs) - */ - def checkVerify(input: A, expected: Expected[B]): Unit = { - checkVerifyVersion(input, expected, 0) - checkVerifyVersion(input, expected, 1) + activatedVersionInTests) } /** Executes the default feature verification wrapper script for the specific ErgoTree * version. * @param input the given input * @param expected the given expected results (values and costs) - * @param scriptVersion version to use when the test ErgoTree is created */ - def checkVerifyVersion(input: A, expected: Expected[B], scriptVersion: Byte): Unit = { + def checkVerify(input: A, expected: Expected[B]): Unit = { val tpeA = Evaluation.rtypeToSType(oldF.tA) val tpeB = Evaluation.rtypeToSType(oldF.tB) @@ -303,7 +293,7 @@ class SigmaDslTesting extends PropSpec pkAlice, DeserializeRegister(ErgoBox.R5, SSigmaProp), // deserialize pkBob DeserializeContext(2, SSigmaProp))) // deserialize pkCarol - val header = ErgoTree.headerWithVersion(scriptVersion) + val header = ErgoTree.headerWithVersion(ergoTreeVersionInTests) ErgoTree.withSegregation(header, sigmastate.SigmaOr(prop, multisig)) } diff --git a/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala b/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala index c77e8605b1..90c5246842 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala @@ -114,7 +114,7 @@ trait SigmaTestingData extends SigmaTestingCommons with SigmaTypeGens { minerPk = SigmaDsl.groupGenerator, votes = Colls.emptyColl[Byte] ) - val ergoCtx = new ErgoLikeContext( + def ergoCtx = new ErgoLikeContext( lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, boxesToSpend = IndexedSeq(inBox), spendingTransaction = new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(DataInput(dataBox.id)), IndexedSeq(outBox)), @@ -122,5 +122,5 @@ trait SigmaTestingData extends SigmaTestingCommons with SigmaTypeGens { extension = ContextExtension(Map(2.toByte -> IntConstant(10))), validationSettings = ValidationRules.currentSettings, costLimit = ScriptCostLimit.value, initCost = 0L, - activatedScriptVersion = ActivatedVersionInTest) + activatedScriptVersion = activatedVersionInTests) } From 30deff40310a03f6cf71ef615363b792e89a081b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 21 Dec 2020 13:40:45 +0300 Subject: [PATCH 24/31] versioned-tests: CostingSpecification.scala --- .../src/main/scala/sigmastate/Values.scala | 7 ++ .../sigmastate/CostingSpecification.scala | 112 +++++++++++------- .../scala/sigmastate/CrossVersionProps.scala | 1 + .../special/sigma/SigmaTestingData.scala | 20 ---- 4 files changed, 80 insertions(+), 60 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index d7416b8e18..3264b1772f 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -1089,6 +1089,9 @@ object Values { def withoutSegregation(root: SigmaPropValue): ErgoTree = ErgoTree(ErgoTree.DefaultHeader, EmptyConstants, root) + def withoutSegregation(headerFlags: Byte, root: SigmaPropValue): ErgoTree = + ErgoTree((ErgoTree.DefaultHeader | headerFlags).toByte, EmptyConstants, root) + implicit def fromProposition(prop: SigmaPropValue): ErgoTree = { prop match { case SigmaPropConstant(_) => withoutSegregation(prop) @@ -1100,6 +1103,10 @@ object Values { withoutSegregation(pk.toSigmaProp) } + def fromSigmaBoolean(headerFlags: Byte, pk: SigmaBoolean): ErgoTree = { + withoutSegregation(headerFlags, pk.toSigmaProp) + } + /** Build ErgoTree via serialization of the value with ConstantSegregationHeader, constants segregated * from the tree and ConstantPlaceholders referring to the segregated constants. * diff --git a/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala index 3d630f471e..ce20a30ea4 100644 --- a/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/CostingSpecification.scala @@ -1,25 +1,24 @@ package sigmastate import org.ergoplatform.SigmaConstants.ScriptCostLimit -import org.ergoplatform.ErgoScriptPredef.TrueProp import org.ergoplatform.validation.ValidationRules 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.{TrueLeaf, BigIntConstant, AvlTreeConstant, ConstantPlaceholder, ByteArrayConstant, IntConstant, ErgoTree, BooleanConstant} +import sigmastate.Values._ import sigmastate.eval.Extensions._ import sigmastate.eval.Sized._ import sigmastate.eval._ import sigmastate.helpers.TestingHelpers._ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestInterpreter} -import sigmastate.interpreter.{ContextExtension, Interpreter} +import sigmastate.interpreter.ContextExtension import sigmastate.interpreter.Interpreter.{ScriptNameProp, ScriptEnv, emptyEnv} import sigmastate.utxo.CostTable import sigmastate.utxo.CostTable._ import special.sigma.{SigmaTestingData, AvlTree} -class CostingSpecification extends SigmaTestingData { +class CostingSpecification extends SigmaTestingData with CrossVersionProps { implicit lazy val IR = new TestingIRContext { // override val okPrintEvaluatedEntries = true substFromCostTable = false @@ -55,39 +54,56 @@ class CostingSpecification extends SigmaTestingData { 3.toByte -> BigIntConstant(BigInt("12345678901").bigInteger) )) val tokenId = Blake2b256("tokenA") - val selfBox = createBox(0, TrueProp, Seq(tokenId -> 10L), - Map(ErgoBox.R4 -> ByteArrayConstant(Array[Byte](1, 2, 3)), - ErgoBox.R5 -> IntConstant(3), - ErgoBox.R6 -> AvlTreeConstant(avlTree))) - 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( - lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, - headers = headers, preHeader = preHeader, - dataBoxes = IndexedSeq(dataBox), - boxesToSpend = IndexedSeq(selfBox), - spendingTransaction = tx, selfIndex = 0, extension, - ValidationRules.currentSettings, ScriptCostLimit.value, - CostTable.interpreterInitCost, activatedVersionInTests - ) - def cost(script: String)(expCost: Int): Unit = { - val ergoTree = compiler.compile(env, script) - val res = interpreter.reduceToCrypto(context, env, ergoTree).get._2 - if (printCosts) - println(script + s" --> cost $res") - res shouldBe ((expCost * CostTable.costFactorIncrease / CostTable.costFactorDecrease) + CostTable.interpreterInitCost).toLong + class TestData { + val headerFlags = ErgoTree.headerWithVersion(ergoTreeVersionInTests) + val selfBox = createBox(0, + ErgoTree.withoutSegregation(headerFlags, TrueSigmaProp), + Seq(tokenId -> 10L), + Map(ErgoBox.R4 -> ByteArrayConstant(Array[Byte](1, 2, 3)), + ErgoBox.R5 -> IntConstant(3), + ErgoBox.R6 -> AvlTreeConstant(avlTree))) + val outBoxA = testBox(10, ErgoTree.fromSigmaBoolean(headerFlags, pkA), 0) + val outBoxB = testBox(20, ErgoTree.fromSigmaBoolean(headerFlags, pkB), 0) + val dataBox = createBox(1000, + ErgoTree.withoutSegregation(headerFlags, TrueSigmaProp), + Seq(tokenId1 -> 10L, tokenId2 -> 20L), + Map(ErgoBox.R4 -> IntConstant(100), ErgoBox.R5 -> BooleanConstant(true))) + val tx = createTransaction(IndexedSeq(dataBox), IndexedSeq(outBoxA, outBoxB)) + val context = new ErgoLikeContext( + lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, + headers = headers, preHeader = preHeader, + dataBoxes = IndexedSeq(dataBox), + boxesToSpend = IndexedSeq(selfBox), + spendingTransaction = tx, selfIndex = 0, extension, + ValidationRules.currentSettings, ScriptCostLimit.value, + CostTable.interpreterInitCost, activatedVersionInTests + ) + + def cost(script: String)(expCost: Int): Unit = { + val ergoTree = compiler.compile(env, script) + val res = interpreter.reduceToCrypto(context, env, ergoTree).get._2 + if (printCosts) + println(script + s" --> cost $res") + res shouldBe ((expCost * CostTable.costFactorIncrease / CostTable.costFactorDecrease) + CostTable.interpreterInitCost).toLong + } + + val ContextVarAccess = getVarCost + selectField // `getVar(id)` + `.get` + val RegisterAccess = accessRegister + selectField // `getReg(id)` + `.get` + val GTConstCost = comparisonCost + constCost + val LengthGTConstCost = collLength + GTConstCost + val LengthGTCost = collLength + comparisonCost // can be used when constCost is already accumulated + + val OutputsCost = selectField + accessBox * tx.outputs.length + val InputsCost = selectField + accessBox * context.boxesToSpend.length + val DataInputsCost = selectField + accessBox * context.dataBoxes.length + val HeadersCost = selectField + val PreHeaderCost = selectField + val AccessHeaderCost = selectField + collByIndex + constCost } - val ContextVarAccess = getVarCost + selectField // `getVar(id)` + `.get` - val RegisterAccess = accessRegister + selectField // `getReg(id)` + `.get` - val GTConstCost = comparisonCost + constCost - val LengthGTConstCost = collLength + GTConstCost - val LengthGTCost = collLength + comparisonCost // can be used when constCost is already accumulated - property("basic (smoke) tests") { - + val d = new TestData; import d._ cost("{ getVar[Boolean](2).get }")(ContextVarAccess) cost("{ getVar[Int](1).get > 1 }")(ContextVarAccess + GTConstCost) @@ -104,6 +120,7 @@ class CostingSpecification extends SigmaTestingData { } property("logical op costs") { + val d = new TestData; import d._ cost("{ val cond = getVar[Boolean](2).get; cond && cond }")(ContextVarAccess + logicCost) cost("{ val cond = getVar[Boolean](2).get; cond || cond }")(ContextVarAccess + logicCost) cost("{ val cond = getVar[Boolean](2).get; cond || cond && true }")(ContextVarAccess + logicCost * 2 + constCost) @@ -115,27 +132,33 @@ class CostingSpecification extends SigmaTestingData { } property("atLeast costs") { + val d = new TestData; import d._ cost("{ atLeast(2, Coll(pkA, pkB, pkB)) }")( concreteCollectionItemCost * 3 + collToColl + proveDlogEvalCost * 2 + logicCost + constCost) } property("allZK costs") { + val d = new TestData; import d._ cost("{ pkA && pkB }") (proveDlogEvalCost * 2 + sigmaAndCost * 2) } property("anyZK costs") { + val d = new TestData; import d._ cost("{ pkA || pkB }") (proveDlogEvalCost * 2 + sigmaOrCost * 2) } property("blake2b256 costs") { + val d = new TestData; import d._ cost("{ blake2b256(key1).size > 0 }") (constCost + hashPerKb + LengthGTConstCost) } property("sha256 costs") { + val d = new TestData; import d._ cost("{ sha256(key1).size > 0 }") (constCost + hashPerKb + LengthGTConstCost) } property("byteArrayToBigInt") { + val d = new TestData; import d._ cost("{ byteArrayToBigInt(Coll[Byte](1.toByte)) > 0 }")( constCost // byte const + collToColl // concrete collection @@ -144,6 +167,7 @@ class CostingSpecification extends SigmaTestingData { } property("byteArrayToLong") { + val d = new TestData; import d._ cost("{ byteArrayToLong(Coll[Byte](1.toByte, 1.toByte, 1.toByte, 1.toByte, 1.toByte, 1.toByte, 1.toByte, 1.toByte)) > 0 }") ( constCost // byte const + collToColl // concrete collection @@ -152,22 +176,27 @@ class CostingSpecification extends SigmaTestingData { } property("longToByteArray") { + val d = new TestData; import d._ cost("{ longToByteArray(1L).size > 0 }") (constCost + castOp + LengthGTConstCost) } property("decodePoint and GroupElement.getEncoded") { + val d = new TestData; import d._ cost("{ decodePoint(groupGenerator.getEncoded) == groupGenerator }") (selectField + selectField + decodePointCost + comparisonCost) } property("GroupElement.negate") { + val d = new TestData; import d._ cost("{ groupGenerator.negate != groupGenerator }") (selectField + negateGroup + comparisonCost) } property("GroupElement.exp") { + val d = new TestData; import d._ cost("{ groupGenerator.exp(getVar[BigInt](3).get) == groupGenerator }") (selectField + expCost + ContextVarAccess + comparisonCost) } property("SELF box operations cost") { + val d = new TestData; import d._ cost("{ SELF.value > 0 }")(accessBox + extractCost + GTConstCost) cost("{ SELF.id.size > 0 }")(accessBox + extractCost + LengthGTConstCost) cost("{ SELF.tokens.size > 0 }")(accessBox + extractCost + LengthGTConstCost) @@ -175,14 +204,8 @@ class CostingSpecification extends SigmaTestingData { cost("{ SELF.R5[Int].get > 0 }")(accessBox + RegisterAccess + GTConstCost) } - lazy val OutputsCost = selectField + accessBox * tx.outputs.length - lazy val InputsCost = selectField + accessBox * context.boxesToSpend.length - lazy val DataInputsCost = selectField + accessBox * context.dataBoxes.length - lazy val HeadersCost = selectField - lazy val PreHeaderCost = selectField - lazy val AccessHeaderCost = selectField + collByIndex + constCost - property("Global operations cost") { + val d = new TestData; import d._ // TODO costing: related to https://github.com/ScorexFoundation/sigmastate-interpreter/issues/479 // cost("{ groupGenerator.isIdentity > 0 }")(selectField + selectField + GTConstCost) @@ -192,6 +215,7 @@ class CostingSpecification extends SigmaTestingData { } property("Context operations cost") { + val d = new TestData; import d._ cost("{ HEIGHT > 0 }")(selectField + GTConstCost) cost("{ OUTPUTS.size > 0 }")(OutputsCost + LengthGTConstCost) cost("{ INPUTS.size > 0 }")(InputsCost + LengthGTConstCost) @@ -204,6 +228,7 @@ class CostingSpecification extends SigmaTestingData { } property("PreHeader operations cost") { + val d = new TestData; import d._ cost("{ CONTEXT.preHeader.version > 0 }")(PreHeaderCost + selectField + castOp + GTConstCost) cost("{ CONTEXT.preHeader.parentId.size > 0 }")(PreHeaderCost + selectField + LengthGTConstCost) cost("{ CONTEXT.preHeader.timestamp > 0L }")(PreHeaderCost + selectField + GTConstCost) @@ -217,6 +242,7 @@ class CostingSpecification extends SigmaTestingData { } property("Header operations cost") { + val d = new TestData; import d._ val header = "CONTEXT.headers(0)" cost(s"{ $header.id.size > 0 }")(AccessHeaderCost + selectField + LengthGTCost) cost(s"{ $header.version > 0 }")(AccessHeaderCost + selectField + castOp + comparisonCost) @@ -245,6 +271,7 @@ class CostingSpecification extends SigmaTestingData { } property("AvlTree operations cost") { + val d = new TestData; import d._ val rootTree = "LastBlockUtxoRootHash" // cost(s"{ $rootTree.digest.size > 0 }")(AccessRootHash + selectField + LengthGTConstCost) // cost(s"{ $rootTree.enabledOperations > 0 }")(AccessRootHash + selectField + castOp + GTConstCost) @@ -290,6 +317,7 @@ class CostingSpecification extends SigmaTestingData { } property("Coll operations cost") { + val d = new TestData; import d._ val coll = "OUTPUTS" val nOutputs = tx.outputs.length val collBytes = "CONTEXT.headers(0).id" @@ -338,6 +366,7 @@ class CostingSpecification extends SigmaTestingData { } property("Option operations cost") { + val d = new TestData; import d._ val opt = "SELF.R5[Int]" val accessOpt = accessBox + accessRegister cost(s"{ $opt.get > 0 }")(accessOpt + selectField + GTConstCost) @@ -350,10 +379,12 @@ class CostingSpecification extends SigmaTestingData { } property("TrueLeaf cost") { + val d = new TestData; import d._ cost("{ true }")(constCost) } property("ErgoTree with TrueLeaf costs") { + val d = new TestData; import d._ val tree = ErgoTree(16, IndexedSeq(TrueLeaf), BoolToSigmaProp(ConstantPlaceholder(0, SBoolean))) val pr = interpreter.prove(tree, context, fakeMessage).get @@ -374,6 +405,7 @@ class CostingSpecification extends SigmaTestingData { } property("laziness of AND, OR costs") { + val d = new TestData; import d._ cost("{ val cond = getVar[Boolean](2).get; !(!cond && (1 / 0 == 1)) }")( ContextVarAccess + constCost * 2 + logicCost * 3 + multiply + comparisonCost) cost("{ val cond = getVar[Boolean](2).get; (cond || (1 / 0 == 1)) }")( diff --git a/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala b/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala index 7c737d3d9e..ac3bd3c101 100644 --- a/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala +++ b/sigmastate/src/test/scala/sigmastate/CrossVersionProps.scala @@ -28,6 +28,7 @@ trait CrossVersionProps extends PropSpecLike with TestsBase { } } } + } } } diff --git a/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala b/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala index 90c5246842..0568b8ec28 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaTestingData.scala @@ -61,17 +61,6 @@ trait SigmaTestingData extends SigmaTestingCommons with SigmaTypeGens { val tokenId1: Digest32 = Blake2b256("id1") val tokenId2: Digest32 = Blake2b256("id2") - val inBox = createBox(10, TrivialProp.TrueProp, - Seq(tokenId1 -> 10L, tokenId2 -> 20L), - Map(ErgoBox.R4 -> IntConstant(100), ErgoBox.R5 -> BooleanConstant(true))) - - val dataBox = createBox(1000, TrivialProp.TrueProp, - Seq(tokenId1 -> 10L, tokenId2 -> 20L), - Map(ErgoBox.R4 -> IntConstant(100), ErgoBox.R5 -> BooleanConstant(true))) - - val outBox = createBox(10, TrivialProp.TrueProp, - Seq(tokenId1 -> 10L, tokenId2 -> 20L), - Map(ErgoBox.R4 -> IntConstant(100), ErgoBox.R5 -> BooleanConstant(true))) val header1: Header = CHeader(Blake2b256("Header.id").toColl, 0, @@ -114,13 +103,4 @@ trait SigmaTestingData extends SigmaTestingCommons with SigmaTypeGens { minerPk = SigmaDsl.groupGenerator, votes = Colls.emptyColl[Byte] ) - def ergoCtx = new ErgoLikeContext( - lastBlockUtxoRoot = header2.stateRoot.asInstanceOf[CAvlTree].treeData, - boxesToSpend = IndexedSeq(inBox), - spendingTransaction = new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(DataInput(dataBox.id)), IndexedSeq(outBox)), - selfIndex = 0, headers = headers, preHeader = preHeader, dataBoxes = IndexedSeq(dataBox), - extension = ContextExtension(Map(2.toByte -> IntConstant(10))), - validationSettings = ValidationRules.currentSettings, - costLimit = ScriptCostLimit.value, initCost = 0L, - activatedScriptVersion = activatedVersionInTests) } From 238627eb90500e9f95f7f4b70f94a9893474942e Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 21 Dec 2020 18:57:38 +0300 Subject: [PATCH 25/31] versioned-tests: passing activatedVersionInTests to test contexts (part 1) --- .../ErgoAddressSpecification.scala | 4 +- .../ergoplatform/ErgoScriptPredefSpec.scala | 13 +++--- .../sigmastate/CalcSha256Specification.scala | 2 +- .../scala/sigmastate/FailingToProveSpec.scala | 6 ++- .../ScriptVersionSwitchSpecification.scala | 6 ++- .../SoftForkabilitySpecification.scala | 2 +- .../TestingInterpreterSpecification.scala | 2 +- .../sigmastate/eval/ErgoScriptTestkit.scala | 7 ++-- .../helpers/ErgoLikeContextTesting.scala | 26 +++--------- .../helpers/ErgoTransactionValidator.scala | 4 +- .../helpers/SigmaTestingCommons.scala | 16 ++++--- .../DeserializationResilience.scala | 2 +- .../SigSerializerSpecification.scala | 2 +- .../utxo/AVLTreeScriptsSpecification.scala | 8 ++-- .../utxo/BasicOpsSpecification.scala | 2 +- .../BlockchainSimulationSpecification.scala | 19 +++++---- .../CollectionOperationsSpecification.scala | 16 +++---- .../utxo/ComplexSigSpecification.scala | 36 ++++++++-------- .../utxo/ContextEnrichingSpecification.scala | 10 ++--- .../ErgoLikeInterpreterSpecification.scala | 42 +++++++++---------- .../utxo/ThresholdSpecification.scala | 8 ++-- .../BlockchainSimulationSpecification.scala | 10 ++--- .../BlockchainSimulationTestingCommons.scala | 11 ++--- .../AtomicSwapExampleSpecification.scala | 16 ++++--- .../examples/CoinEmissionSpecification.scala | 3 +- ...alletAdvContractExampleSpecification.scala | 6 ++- ...ldWalletContractExampleSpecification.scala | 12 ++++-- .../examples/CoopExampleSpecification.scala | 2 +- .../DHTupleExampleSpecification.scala | 2 +- .../DemurrageExampleSpecification.scala | 12 +++--- .../examples/FsmExampleSpecification.scala | 12 +++--- .../sigmastate/utxo/examples/IcoExample.scala | 6 +-- .../utxo/examples/LetsSpecification.scala | 2 +- .../examples/MASTExampleSpecification.scala | 4 +- .../examples/MixExampleSpecification.scala | 6 +-- .../OracleExamplesSpecification.scala | 4 +- .../RPSGameExampleSpecification.scala | 17 ++++---- .../ReversibleTxExampleSpecification.scala | 6 +-- .../utxo/examples/Rule110Specification.scala | 15 ++++--- .../TimedPaymentExampleSpecification.scala | 6 ++- .../XorGameExampleSpecification.scala | 12 ++++-- .../special/sigma/SigmaDslSpecification.scala | 2 +- .../scala/special/sigma/SigmaDslTesting.scala | 3 +- 43 files changed, 212 insertions(+), 190 deletions(-) diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala index bc4d2e733f..10a61f9a4b 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala @@ -186,7 +186,7 @@ class ErgoAddressSpecification extends SigmaDslTesting with TryValues { def testPay2SHAddress(address: Pay2SHAddress, scriptBytes: Array[Byte])(implicit IR: IRContext) = { val scriptId = 1.toByte val boxToSpend = testBox(10, address.script, creationHeight = 5) - val ctx = ErgoLikeContextTesting.dummy(boxToSpend) + val ctx = ErgoLikeContextTesting.dummy(boxToSpend, activatedVersionInTests) .withExtension(ContextExtension(Seq( scriptId -> ByteArrayConstant(scriptBytes) // provide script bytes in context variable ).toMap)) @@ -217,7 +217,7 @@ class ErgoAddressSpecification extends SigmaDslTesting with TryValues { def testPay2SHAddress(address: Pay2SHAddress, script: (Byte, EvaluatedValue[_ <: SType]), costLimit: Int = ScriptCostLimit.value): CostedProverResult = { val boxToSpend = testBox(10, address.script, creationHeight = 5) - val ctx = copyContext(ErgoLikeContextTesting.dummy(boxToSpend) + val ctx = copyContext(ErgoLikeContextTesting.dummy(boxToSpend, activatedVersionInTests) .withExtension(ContextExtension(Seq( script // provide script bytes in context variable ).toMap)))(costLimit = costLimit) diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala index f0f9b17495..0e5c1291e7 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala @@ -56,7 +56,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { minerPubkey = pk, boxesToSpend = inputBoxes, spendingTransaction, - self = inputBox) + self = inputBox, activatedVersionInTests) val pr = prover.prove(emptyEnv + (ScriptNameProp -> "boxCreationHeight_prove"), prop, ctx, fakeMessage).get verifier.verify(emptyEnv + (ScriptNameProp -> "boxCreationHeight_verify"), prop, ctx, pr, fakeMessage).get._1 shouldBe true } @@ -114,7 +114,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction, - self = inputBoxes.head) + self = inputBoxes.head, activatedVersionInTests) val pr = prover.prove(emptyEnv + (ScriptNameProp -> "checkSpending_prove"), prop, ctx, fakeMessage).get verifier.verify(emptyEnv + (ScriptNameProp -> "checkSpending_verify"), prop, ctx, pr, fakeMessage).get._1 shouldBe true } @@ -135,14 +135,14 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction, - self = inputBoxes.head) + self = inputBoxes.head, activatedVersionInTests) val prevBlockCtx = ErgoLikeContextTesting( currentHeight = inputBoxes.head.creationHeight + settings.minerRewardDelay - 1, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction, - self = inputBoxes.head) + self = inputBoxes.head, activatedVersionInTests) // should not be able to collect before minerRewardDelay val prove = prover.prove(emptyEnv + (ScriptNameProp -> "rewardOutputScript_prove"), prop, ctx, fakeMessage).get @@ -224,7 +224,8 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction, - self = inputBoxes.head).withCostLimit(CostTable.ScriptLimit * 10) + self = inputBoxes.head, + activatedVersionInTests).withCostLimit(CostTable.ScriptLimit * 10) val pr = prover.prove(emptyEnv + (ScriptNameProp -> "tokenThresholdScript_prove"), prop, ctx, fakeMessage).getOrThrow verifier.verify(emptyEnv + (ScriptNameProp -> "tokenThresholdScript_verify"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true @@ -301,7 +302,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { minerPubkey = pkBytes, boxesToSpend = inputBoxes, spendingTransaction, - self = inputBoxes.head) + self = inputBoxes.head, activatedVersionInTests) val pr = prover.prove(emptyEnv + (ScriptNameProp -> "checkRewardTx_prove"), prop, ctx, fakeMessage).getOrThrow verifier.verify(emptyEnv + (ScriptNameProp -> "checkRewardTx_verify"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true spendingTransaction diff --git a/sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala b/sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala index 5c86926b8c..2e1efcf7b1 100644 --- a/sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala +++ b/sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala @@ -29,7 +29,7 @@ class CalcSha256Specification extends SigmaTestingCommons { property("CalcSha256: Should pass standard tests.") { val int = new ContextEnrichingTestProvingInterpreter() - val ctx = ErgoLikeContextTesting.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf, activatedVersionInTests) forAll(objects) { (in, result) => val expectedResult = decodeString(result) val calcSha256 = EQ(CalcSha256(stringToByteConstant(in)), expectedResult) diff --git a/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala b/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala index ed166795f3..753937abf8 100644 --- a/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala +++ b/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala @@ -42,7 +42,8 @@ class FailingToProveSpec extends SigmaTestingCommons { boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx, self = selfBox, - minerPubkey = ErgoLikeContextTesting.dummyPubkey) + minerPubkey = ErgoLikeContextTesting.dummyPubkey, + activatedVersion = activatedVersionInTests) val proof = interpreter.prove(emptyEnv + (ScriptNameProp -> "prove"), compiledScript, ctx, fakeMessage).success.value.proof verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), compiledScript, ctx, proof, fakeMessage) should be a 'success } @@ -76,7 +77,8 @@ class FailingToProveSpec extends SigmaTestingCommons { boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx, self = selfBox, - minerPubkey = ErgoLikeContextTesting.dummyPubkey) + minerPubkey = ErgoLikeContextTesting.dummyPubkey, + activatedVersion = activatedVersionInTests) val proof = interpreter.prove(emptyEnv + (ScriptNameProp -> "prove"), compiledScript, ctx, fakeMessage).success.value.proof verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), compiledScript, ctx, proof, fakeMessage) should be a 'success } diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index 98730eaef5..f80f9899ec 100644 --- a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -70,7 +70,8 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { ) val ctx = copyContext(ErgoLikeContextTesting.dummy( - createBox(0, ergoTree, additionalRegisters = newRegisters) + createBox(0, ergoTree, additionalRegisters = newRegisters), + activatedVersionInTests ).withBindings( 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA) ).asInstanceOf[ErgoLikeContext])(activatedScriptVersion = activatedScriptVersion) @@ -87,7 +88,8 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { ) val ctx = copyContext(ErgoLikeContextTesting.dummy( - createBox(0, ergoTree, additionalRegisters = newRegisters) + createBox(0, ergoTree, additionalRegisters = newRegisters), + activatedVersionInTests ).withBindings( 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA) ).asInstanceOf[ErgoLikeContext])(activatedScriptVersion = activatedScriptVersion) diff --git a/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index 5cfbf67957..02469a1db7 100644 --- a/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -47,7 +47,7 @@ class SoftForkabilitySpecification extends SigmaTestingData { def createContext(h: Int, tx: ErgoLikeTransaction, vs: SigmaValidationSettings) = ErgoLikeContextTesting(h, AvlTreeData.dummy, ErgoLikeContextTesting.dummyPubkey, IndexedSeq(fakeSelf), - tx, fakeSelf, vs = vs) + tx, fakeSelf, vs = vs, activatedVersion = activatedVersionInTests) def proveTx(name: String, tx: ErgoLikeTransaction, vs: SigmaValidationSettings): ProverResult = { val env = Map(ScriptNameProp -> (name + "_prove")) diff --git a/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index ba1c3e3abb..eb9364102b 100644 --- a/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -28,7 +28,7 @@ class TestingInterpreterSpecification extends SigmaTestingCommons { ErgoLikeContextTesting(h, AvlTreeData.dummy, ErgoLikeContextTesting.dummyPubkey, IndexedSeq(fakeSelf), ErgoLikeTransaction(IndexedSeq.empty, IndexedSeq.empty), - fakeSelf) + fakeSelf, activatedVersionInTests) property("Reduction to crypto #1") { forAll() { i: Int => diff --git a/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala b/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala index 593806f3f3..279b517c9b 100644 --- a/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala @@ -4,7 +4,7 @@ import org.ergoplatform.ErgoAddressEncoder.TestnetNetworkPrefix import org.ergoplatform.validation.ValidationSpecification import scala.util.Success -import sigmastate.{AvlTreeData, SType} +import sigmastate.{AvlTreeData, SType, TestsBase} import sigmastate.Values.{EvaluatedValue, SValue, SigmaPropConstant, Value, BigIntArrayConstant} import org.ergoplatform.{Context => _, _} import sigmastate.utxo.CostTable @@ -20,7 +20,7 @@ import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer import scala.language.implicitConversions trait ErgoScriptTestkit extends ContractsTestkit with LangTests - with ValidationSpecification { self: BaseCtxTests => + with ValidationSpecification with TestsBase { self: BaseCtxTests => implicit lazy val IR: TestContext with IRContext = new TestContext with IRContext with CompiletimeCosting @@ -41,7 +41,7 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(boxToSpend), spendingTransaction = tx1, - self = boxToSpend, + self = boxToSpend, activatedVersionInTests, extension = ContextExtension(extension)) ergoCtx } @@ -76,6 +76,7 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests boxesToSpend = IndexedSeq(boxToSpend), spendingTransaction = tx1, self = boxToSpend, + activatedVersionInTests, extension = ContextExtension(Map( backerPubKeyId -> SigmaPropConstant(backerPubKey), projectPubKeyId -> SigmaPropConstant(projectPubKey), diff --git a/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala index 91974ff196..af409d7b50 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala @@ -41,12 +41,13 @@ object ErgoLikeContextTesting { boxesToSpend: IndexedSeq[ErgoBox], spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], self: ErgoBox, + activatedVersion: Byte, extension: ContextExtension = ContextExtension.empty, vs: SigmaValidationSettings = ValidationRules.currentSettings): ErgoLikeContext = new ErgoLikeContext( lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), noBoxes, boxesToSpend, spendingTransaction, boxesToSpend.indexOf(self), extension, vs, - ScriptCostLimit.value, initCost = 0L, Interpreter.MaxSupportedScriptVersion) + ScriptCostLimit.value, initCost = 0L, activatedVersion) def apply(currentHeight: Height, lastBlockUtxoRoot: AvlTreeData, @@ -62,27 +63,10 @@ object ErgoLikeContextTesting { initCost = 0L, Interpreter.MaxSupportedScriptVersion) - def dummy(selfDesc: ErgoBox): ErgoLikeContext = ErgoLikeContextTesting(currentHeight = 0, + def dummy(selfDesc: ErgoBox, activatedVersion: Byte): ErgoLikeContext = ErgoLikeContextTesting(currentHeight = 0, lastBlockUtxoRoot = AvlTreeData.dummy, dummyPubkey, boxesToSpend = IndexedSeq(selfDesc), - spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), self = selfDesc) - - def fromTransaction(tx: ErgoLikeTransaction, - blockchainState: BlockchainState, - boxesReader: ErgoBoxReader, - inputIndex: Int): Try[ErgoLikeContext] = Try { - - val boxes = tx.inputs.map(_.boxId).map(id => boxesReader.byId(id).get) - - val proverExtension = tx.inputs(inputIndex).spendingProof.extension - - ErgoLikeContextTesting(blockchainState.currentHeight, - blockchainState.lastBlockUtxoRoot, - dummyPubkey, - boxes, - tx, - boxes(inputIndex), - proverExtension) - } + spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), self = selfDesc, + activatedVersion = activatedVersion) val noInputs: Array[Box] = Array[Box]() val noOutputs: Array[Box] = Array[Box]() diff --git a/sigmastate/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala b/sigmastate/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala index 1d1717ff6b..dbd54b450e 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/ErgoTransactionValidator.scala @@ -11,7 +11,7 @@ class ErgoLikeTestInterpreter(implicit override val IR: IRContext) extends ErgoL override type CTX = ErgoLikeContext } -class ErgoTransactionValidator(implicit IR: IRContext) { +class ErgoTransactionValidator(activatedVersion: Byte)(implicit IR: IRContext) { val verifier = new ErgoLikeTestInterpreter() def validate(tx: ErgoLikeTransaction, @@ -37,7 +37,7 @@ class ErgoTransactionValidator(implicit IR: IRContext) { val context = ErgoLikeContextTesting(blockchainState.currentHeight, blockchainState.lastBlockUtxoRoot, minerPubkey, boxes, - tx, box, proverExtension) + tx, box, activatedVersion, proverExtension) val verificationResult = verifier.verify( emptyEnv + (ScriptNameProp -> s"height_${blockchainState.currentHeight }_verify"), box.ergoTree, context, proof, msg) diff --git a/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala index d2d7deea37..0d2cf49649 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/SigmaTestingCommons.scala @@ -18,7 +18,7 @@ import sigmastate.interpreter.Interpreter.{ScriptNameProp, ScriptEnv} import sigmastate.interpreter.{CryptoConstants, Interpreter} import sigmastate.lang.{Terms, TransformingSigmaBuilder, SigmaCompiler} import sigmastate.serialization.{ValueSerializer, SigmaSerializer} -import sigmastate.{SGroupElement, SType} +import sigmastate.{SGroupElement, SType, TestsBase} import sigmastate.eval.{CompiletimeCosting, IRContext, Evaluation, _} import sigmastate.interpreter.CryptoConstants.EcPointType import sigmastate.utils.Helpers._ @@ -31,11 +31,13 @@ trait SigmaTestingCommons extends PropSpec with PropertyChecks with GeneratorDrivenPropertyChecks with Matchers with TestUtils with TestContexts with ValidationSpecification - with NegativeTesting { + with NegativeTesting + with TestsBase { val fakeSelf: ErgoBox = createBox(0, TrueProp) - val fakeContext: ErgoLikeContext = ErgoLikeContextTesting.dummy(fakeSelf) + def fakeContext: ErgoLikeContext = + ErgoLikeContextTesting.dummy(fakeSelf, activatedVersionInTests) //fake message, in a real-life a message is to be derived from a spending transaction val fakeMessage = Blake2b256("Hello World") @@ -203,9 +205,11 @@ trait SigmaTestingCommons extends PropSpec 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: _*) + val ergoCtx = ErgoLikeContextTesting.dummy( + createBox(0, TrueProp), activatedVersionInTests + ).withBindings(1.toByte -> Constant[SType](x.asInstanceOf[SType#WrappedType], tpeA)) + .withBindings(bindings: _*) + val calcCtx = ergoCtx.toSigmaContext(isCost = false).asInstanceOf[CostingDataContext] val costCtx = calcCtx.copy(isCost = true) (costCtx, calcCtx) diff --git a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala index 2b56a8372a..4f42356699 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala @@ -265,7 +265,7 @@ class DeserializationResilience extends SerializationSpecification assertExceptionThrown({ val verifier = new ErgoLikeTestInterpreter val pr = CostedProverResult(Array[Byte](), ContextExtension(Map()), 0L) - val ctx = ErgoLikeContextTesting.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf, activatedVersionInTests) val (res, calcTime) = BenchmarkUtil.measureTime { verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), ErgoTree(ErgoTree.DefaultHeader, IndexedSeq(), recursiveScript), ctx, pr, fakeMessage) diff --git a/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala index 751df5c0cf..def72b52ed 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala @@ -78,7 +78,7 @@ class SigSerializerSpecification extends SigmaTestingCommons with ObjectGenerato minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) .withCostLimit(Long.MaxValue) // To avoid occasional cost limit exceptions which are irrelevant here try { diff --git a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala index f230460d73..dadaac6451 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala @@ -225,7 +225,7 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, - self = s) + self = s, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get verifier.verify(prop, ctx, pr, fakeMessage).get._1 shouldBe true @@ -259,7 +259,7 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), createTransaction(testBox(1, recipientProposition, 0)), - self = selfBox) + self = selfBox, activatedVersionInTests) avlProver.performOneOperation(Lookup(treeElements.head._1)) val bigLeafProof = avlProver.generateProof() @@ -336,7 +336,7 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), - spendingTransaction, self = s) + spendingTransaction, self = s, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) @@ -388,7 +388,7 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), - spendingTransaction, self = s) + spendingTransaction, self = s, activatedVersionInTests) val pr = prover.prove(env + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 5af6798676..d73788547d 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -81,7 +81,7 @@ class BasicOpsSpecification extends SigmaTestingCommons { val ctx = ErgoLikeContextTesting(currentHeight = 0, lastBlockUtxoRoot = AvlTreeData.dummy, ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(boxToSpend), - spendingTransaction = tx, self = boxToSpend) + spendingTransaction = tx, self = boxToSpend, activatedVersionInTests) val pr = prover.prove(env + (ScriptNameProp -> s"${name}_prove"), prop, ctx, fakeMessage).getOrThrow diff --git a/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala index 70ebaa4f04..c91bcd997b 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala @@ -43,6 +43,7 @@ class BlockchainSimulationSpecification extends SigmaTestingCommons { IndexedSeq(box), tx, box, + activatedVersionInTests, ContextExtension.empty) val env = emptyEnv + (ScriptNameProp -> s"height_${state.state.currentHeight}_prove") val proverResult = miner.prove(env, box.ergoTree, context, tx.messageToSign).get @@ -54,7 +55,7 @@ class BlockchainSimulationSpecification extends SigmaTestingCommons { } property("apply one valid block") { - val state = ValidationState.initialState() + val state = ValidationState.initialState(activatedVersionInTests) val miner = new ErgoLikeTestProvingInterpreter() val block = generateBlock(state, miner, 0) val updStateTry = state.applyBlock(block) @@ -62,7 +63,7 @@ class BlockchainSimulationSpecification extends SigmaTestingCommons { } property("too costly block") { - val state = ValidationState.initialState() + val state = ValidationState.initialState(activatedVersionInTests) val miner = new ErgoLikeTestProvingInterpreter() val block = generateBlock(state, miner, 0) val updStateTry = state.applyBlock(block, maxCost = 1) @@ -70,7 +71,7 @@ class BlockchainSimulationSpecification extends SigmaTestingCommons { } property("apply many blocks") { - val state = ValidationState.initialState() + val state = ValidationState.initialState(activatedVersionInTests) val miner = new ErgoLikeTestProvingInterpreter() @tailrec @@ -95,7 +96,7 @@ class BlockchainSimulationSpecification extends SigmaTestingCommons { def bench(numberOfBlocks: Int): Unit = { - val state = ValidationState.initialState() + val state = ValidationState.initialState(activatedVersionInTests) val miner = new ErgoLikeTestProvingInterpreter() val (_, time) = (0 until numberOfBlocks).foldLeft(state -> 0L) { case ((s, timeAcc), h) => @@ -185,8 +186,8 @@ object BlockchainSimulationSpecification { } - case class ValidationState(state: BlockchainState, boxesReader: InMemoryErgoBoxReader)(implicit IR: IRContext) { - val validator = new ErgoTransactionValidator + case class ValidationState(state: BlockchainState, boxesReader: InMemoryErgoBoxReader, activatedVersion: Byte)(implicit IR: IRContext) { + val validator = new ErgoTransactionValidator(activatedVersion) def applyBlock(block: Block, maxCost: Int = MaxBlockCost): Try[ValidationState] = Try { val height = state.currentHeight + 1 @@ -203,7 +204,7 @@ object BlockchainSimulationSpecification { boxesReader.applyBlock(block) val newState = BlockchainState(height, state.lastBlockUtxoRoot.copy(digest = boxesReader.digest)) - ValidationState(newState, boxesReader) + ValidationState(newState, boxesReader, activatedVersion) } } @@ -219,7 +220,7 @@ object BlockchainSimulationSpecification { ErgoLikeContextTesting.dummyPubkey ) - def initialState(block: Block = initBlock)(implicit IR: IRContext): ValidationState = { + def initialState(activatedVersion: Byte, block: Block = initBlock)(implicit IR: IRContext): ValidationState = { val keySize = 32 val prover = new BatchProver(keySize, None) @@ -230,7 +231,7 @@ object BlockchainSimulationSpecification { val boxReader = new InMemoryErgoBoxReader(prover) - ValidationState(bs, boxReader).applyBlock(block).get + ValidationState(bs, boxReader, activatedVersion).applyBlock(block).get } } diff --git a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala index 470db0f676..ad86946261 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala @@ -26,7 +26,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = toSpend, spendingTransaction = createTransaction(outputs), - self = selfBox) + self = selfBox, activatedVersionInTests) } private def assertProof(code: String, @@ -103,7 +103,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = Array(fakeSelf), spendingTransaction, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) { val pr = prover.prove(prop, ctx, fakeMessage).get @@ -121,7 +121,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = Array(fakeSelf), spendingTransaction = tx2, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) prover.prove(prop, ctx2, fakeMessage).isFailure shouldBe true } @@ -151,7 +151,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get verifier.verify(prop, ctx, pr, fakeMessage).get._1 shouldBe true @@ -181,7 +181,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) prover.prove(prop, ctx, fakeMessage).isSuccess shouldBe false } @@ -221,7 +221,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, - self = s) + self = s, activatedVersionInTests) val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).get verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).get._1 shouldBe true @@ -264,7 +264,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, - self = s) + self = s, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get verifier.verify(prop, ctx, pr, fakeMessage).get._1 shouldBe true @@ -295,7 +295,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s), spendingTransaction, - self = s) + self = s, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get verifier.verify(prop, ctx, pr, fakeMessage) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala index 2a88e05826..7ad3cd5fbf 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala @@ -43,7 +43,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get verifier.verify(compiledProp, ctx, prA, fakeMessage).get._1 shouldBe true @@ -76,7 +76,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get verifier.verify(compiledProp, ctx, prA, fakeMessage).get._1 shouldBe true @@ -110,7 +110,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get verifier.verify(compiledProp, ctx, prA, fakeMessage).get._1 shouldBe true @@ -145,7 +145,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get verifier.verify(compiledProp, ctx, prA, fakeMessage).get._1 shouldBe true @@ -176,7 +176,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true proverB.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -217,7 +217,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true proverB.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -254,7 +254,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true proverB.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -287,7 +287,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true proverB.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -327,7 +327,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true proverB.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -368,7 +368,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) proverA.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true proverB.prove(compiledProp, ctx, fakeMessage).isFailure shouldBe true @@ -412,7 +412,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get verifier.verify(compiledProp, ctx, prA, fakeMessage).get._1 shouldBe true @@ -450,7 +450,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx1, fakeMessage).get verifier.verify(compiledProp, ctx1, prA, fakeMessage).get._1 shouldBe true val prB = proverB.prove(compiledProp, ctx1, fakeMessage).get @@ -463,7 +463,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prC = proverC.prove(compiledProp, ctx2, fakeMessage).get verifier.verify(compiledProp, ctx2, prC, fakeMessage).get._1 shouldBe true } @@ -492,7 +492,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx1, fakeMessage).get verifier.verify(compiledProp, ctx1, prA, fakeMessage).get._1 shouldBe true @@ -507,7 +507,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA2 = proverA.prove(compiledProp, ctx2, fakeMessage).get verifier.verify(compiledProp, ctx2, prA2, fakeMessage).get._1 shouldBe true @@ -540,7 +540,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx1, fakeMessage).get verifier.verify(compiledProp, ctx1, prA, fakeMessage).get._1 shouldBe true @@ -555,7 +555,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA2 = proverA.prove(compiledProp, ctx2, fakeMessage).get verifier.verify(compiledProp, ctx2, prA2, fakeMessage).get._1 shouldBe true @@ -590,7 +590,7 @@ class ComplexSigSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) // any prover alone (no added secrets) should fail allProvers.foreach(_.prove(prop, ctx, fakeMessage).isFailure shouldBe true) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala index a719c43ade..045c9cc4b5 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala @@ -31,7 +31,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { ) compiledScript shouldBe prop - val ctx = ErgoLikeContextTesting.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf, activatedVersionInTests) val pr = prover.prove(compiledScript, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) @@ -63,7 +63,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { ) compiledScript shouldBe prop - val ctx = ErgoLikeContextTesting.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf, activatedVersionInTests) val pr = prover.prove(compiledScript, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) @@ -93,7 +93,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { val prop = EQ(Xor(GetVarByteArray(k1).get, GetVarByteArray(k2).get), ByteArrayConstant(r)).toSigmaProp compiledScript shouldBe prop - val ctx = ErgoLikeContextTesting.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) @@ -124,7 +124,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { val prop = EQ(CalcBlake2b256(GetVarByteArray(1).get), ByteArrayConstant(Blake2b256(preimage.toArray))).toSigmaProp compiledScript shouldBe prop - val ctx = ErgoLikeContextTesting.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) @@ -152,7 +152,7 @@ class ContextEnrichingSpecification extends SigmaTestingCommons { ByteArrayConstant(Blake2b256(preimage2.append(preimage1).toArray))).toSigmaProp compiledScript shouldBe prop - val ctx = ErgoLikeContextTesting.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get val ctxv = ctx.withExtension(pr.extension) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala index 9c2d2c439a..affba18c96 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala @@ -36,7 +36,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons val h1 = SigmaPropConstant(prover1.dlogSecrets.head.publicImage) val h2 = SigmaPropConstant(prover2.dlogSecrets.head.publicImage) - val ctx = ErgoLikeContextTesting.dummy(fakeSelf) + val ctx = ErgoLikeContextTesting.dummy(fakeSelf, activatedVersionInTests) val e = compile(Map("h1" -> h1.treeWithSegregation.bytes, "h2" -> h2.treeWithSegregation.bytes), "h1 == h1") val exp = TrueLeaf @@ -77,7 +77,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get verifier.verify(prop, ctx, pr, fakeMessage).get._1 shouldBe true @@ -107,7 +107,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get verifier.verify(compiledProp, ctx, prA, fakeMessage).get._1 shouldBe true @@ -134,7 +134,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val prA = proverA.prove(compiledProp, ctx, fakeMessage).get @@ -189,7 +189,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) //before timeout val prA = proverA.prove( @@ -252,7 +252,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get verifier.verify(prop, ctx, pr, fakeMessage) @@ -282,7 +282,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val pr = prover.prove(compiledProp, ctx, fakeMessage).get verifier.verify(compiledProp, ctx, pr, fakeMessage) @@ -318,7 +318,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), createTransaction(testBox(1, recipientProposition, 0)), - self = selfBox) + self = selfBox, activatedVersionInTests) val proof = prover.prove(prop, ctx, fakeMessage).get @@ -362,7 +362,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s1), spendingTransaction, - self = s1) + self = s1, activatedVersionInTests) val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).getOrThrow verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true @@ -377,7 +377,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s2), spendingTransaction, - self = s2) + self = s2, activatedVersionInTests) prover.prove(prop, wrongCtx, fakeMessage).isFailure shouldBe true verifier.verify(prop, wrongCtx, pr, fakeMessage).isFailure shouldBe true @@ -412,7 +412,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), createTransaction(testBox(1, recipientProposition, 0)), - self = selfBox) + self = selfBox, activatedVersionInTests) val proof = prover.prove(prop, ctx, fakeMessage).get @@ -465,7 +465,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(brother, s), spendingTransaction, - self = s) + self = s, activatedVersionInTests) val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove_prop"), prop, ctx, fakeMessage).getOrThrow verifier.verify(emptyEnv + (ScriptNameProp -> "verify_prop"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true @@ -476,7 +476,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(brotherWithWrongId, s), spendingTransaction, - self = s) + self = s, activatedVersionInTests) prover.prove(prop, wrongCtx, fakeMessage).isFailure shouldBe true verifier.verify(prop, wrongCtx, pr, fakeMessage).getOrThrow._1 shouldBe false @@ -545,7 +545,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(friend, s), spendingTransaction, - self = s) + self = s, activatedVersionInTests) val pr1 = prover.prove(prop, ctx1, fakeMessage).success.value verifier.verify(prop, ctx1, pr1, fakeMessage).success.value._1 shouldBe true @@ -556,7 +556,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(s, friend), spendingTransaction, - self = s) + self = s, activatedVersionInTests) val pr2 = prover.prove(prop, ctx2, fakeMessage).success.value verifier.verify(prop, ctx2, pr2, fakeMessage).success.value._1 shouldBe true @@ -570,7 +570,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(friendWithWrongId, s), spendingTransaction, - self = s) + self = s, activatedVersionInTests) prover.prove(prop, wrongCtx1, fakeMessage).isFailure shouldBe true verifier.verify(prop, wrongCtx1, pr1, fakeMessage).success.value._1 shouldBe false @@ -620,7 +620,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(input0, input1, input2, input3), spendingTransaction, - self = input3) + self = input3, activatedVersionInTests) val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx1, fakeMessage).get verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx1, pr, fakeMessage).get._1 shouldBe true @@ -633,7 +633,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons copyBox(input0)(value = 20), // to go through `then` branch of `if` in the script input1, input2, input3), spendingTransaction, - self = input3) + self = input3, activatedVersionInTests) prover.prove(prop, ctx2, fakeMessage).isFailure shouldBe true } @@ -654,7 +654,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(box), createTransaction(IndexedSeq(testBox(10, TrueProp, 0))), - self = box) + self = box, activatedVersionInTests) an[RuntimeException] should be thrownBy prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).getOrThrow @@ -679,7 +679,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(box), createTransaction(IndexedSeq(testBox(10, TrueProp, 0))), - self = box) + self = box, activatedVersionInTests) val pr = prover.prove(prop, ctx, fakeMessage).get // make sure verifier will fail on deserializing context with mismatched type @@ -695,7 +695,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons property("DeserializeContext can return expression of non-Boolean/SigmaProp type") { def prove(ergoTree: ErgoTree, script: (Byte, EvaluatedValue[_ <: SType])): CostedProverResult = { val boxToSpend = testBox(10, ergoTree, creationHeight = 5) - val ctx = ErgoLikeContextTesting.dummy(boxToSpend) + val ctx = ErgoLikeContextTesting.dummy(boxToSpend, activatedVersionInTests) .withExtension( ContextExtension(Seq(script).toMap)) // provide script bytes in context variable diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala index b3a0f1f95e..c69d4e325f 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala @@ -40,7 +40,7 @@ class ThresholdSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val env = Map("pubkeyA" -> pubkeyA, "pubkeyB" -> pubkeyB, "pubkeyC" -> pubkeyC) @@ -119,7 +119,7 @@ class ThresholdSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) case class TestCase(numTrue: Int, vector: Seq[SigmaPropValue], dlogOnlyVector: DlogOnlyVector) case class DlogOnlyVector(v: Seq[SigmaPropValue]) { @@ -289,7 +289,7 @@ class ThresholdSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val verifier = new ErgoLikeTestInterpreter @@ -336,7 +336,7 @@ class ThresholdSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, activatedVersionInTests) val verifier = new ErgoLikeTestInterpreter diff --git a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala index 9214d0bb12..28940cb19e 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala @@ -17,7 +17,7 @@ class BlockchainSimulationSpecification extends BlockchainSimulationTestingCommo implicit lazy val IR = new TestingIRContext property("apply one valid block") { - val state = ValidationState.initialState() + val state = ValidationState.initialState(activatedVersionInTests) val miner = new ErgoLikeTestProvingInterpreter() val block = generateBlock(state, miner, 0) val updStateTry = state.applyBlock(block) @@ -25,7 +25,7 @@ class BlockchainSimulationSpecification extends BlockchainSimulationTestingCommo } property("too costly block") { - val state = ValidationState.initialState() + val state = ValidationState.initialState(activatedVersionInTests) val miner = new ErgoLikeTestProvingInterpreter() val block = generateBlock(state, miner, 0) val updStateTry = state.applyBlock(block, maxCost = 1) @@ -33,13 +33,13 @@ class BlockchainSimulationSpecification extends BlockchainSimulationTestingCommo } property("apply many blocks") { - val state = ValidationState.initialState() + val state = ValidationState.initialState(activatedVersionInTests) val miner = new ErgoLikeTestProvingInterpreter() checkState(state, miner, 0, randomDeepness) } property("apply many blocks with enriched context") { - val state = ValidationState.initialState() + val state = ValidationState.initialState(activatedVersionInTests) val miner = new ErgoLikeTestProvingInterpreter() val varId = 1.toByte val prop = GetVarBoolean(varId).get.toSigmaProp @@ -56,7 +56,7 @@ class BlockchainSimulationSpecification extends BlockchainSimulationTestingCommo def bench(numberOfBlocks: Int): Unit = { - val state = ValidationState.initialState() + val state = ValidationState.initialState(activatedVersionInTests) val miner = new ContextEnrichingTestProvingInterpreter() val (_, time) = (0 until numberOfBlocks).foldLeft(state -> 0L) { case ((s, timeAcc), h) => diff --git a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala index 4612112f85..fc8918652d 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala @@ -58,6 +58,7 @@ trait BlockchainSimulationTestingCommons extends SigmaTestingCommons { IndexedSeq(box), tx, box, + activatedVersionInTests, extension) val env = emptyEnv + (ScriptNameProp -> s"height_${state.state.currentHeight}_prove") val proverResult = prover.prove(env, box.ergoTree, context, tx.messageToSign).get @@ -119,8 +120,8 @@ object BlockchainSimulationTestingCommons extends SigmaTestingCommons { } - case class ValidationState(state: BlockchainState, boxesReader: InMemoryErgoBoxReader)(implicit IR: IRContext) { - val validator = new ErgoTransactionValidator + case class ValidationState(state: BlockchainState, boxesReader: InMemoryErgoBoxReader, activatedVersion: Byte)(implicit IR: IRContext) { + val validator = new ErgoTransactionValidator(activatedVersion) def applyBlock(block: FullBlock, maxCost: Int = MaxBlockCost): Try[ValidationState] = Try { val height = state.currentHeight + 1 @@ -138,7 +139,7 @@ object BlockchainSimulationTestingCommons extends SigmaTestingCommons { boxesReader.applyBlock(block) val newState = BlockchainState(height, state.lastBlockUtxoRoot.copy(digest = boxesReader.digest)) - ValidationState(newState, boxesReader) + ValidationState(newState, boxesReader, activatedVersion) } } @@ -154,7 +155,7 @@ object BlockchainSimulationTestingCommons extends SigmaTestingCommons { ErgoLikeContextTesting.dummyPubkey ) - def initialState(block: FullBlock = initBlock)(implicit IR: IRContext): ValidationState = { + def initialState(activatedVersion: Byte, block: FullBlock = initBlock)(implicit IR: IRContext): ValidationState = { val keySize = 32 val prover = new BatchProver(keySize, None) @@ -165,7 +166,7 @@ object BlockchainSimulationTestingCommons extends SigmaTestingCommons { val boxReader = new InMemoryErgoBoxReader(prover) - ValidationState(bs, boxReader).applyBlock(block).get + ValidationState(bs, boxReader, activatedVersion).applyBlock(block).get } } diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala index 42bcf6bbe5..eb60bbfa6f 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala @@ -10,7 +10,7 @@ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeConte import sigmastate.lang.Terms._ import sigmastate.utxo.SizeOf -class AtomicSwapExampleSpecification extends SigmaTestingCommons { +class AtomicSwapExampleSpecification extends SigmaTestingCommons with CrossVersionProps { private implicit lazy val IR: TestingIRContext = new TestingIRContext /** @@ -103,7 +103,8 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, + activatedVersionInTests) proverB.prove(env, prop1, ctxf1, fakeMessage).isSuccess shouldBe false //A can't withdraw her coins in chain1 (generate a valid proof) @@ -114,7 +115,10 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { currentHeight = height2 + 1, lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, - boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, self = fakeSelf) + boxesToSpend = IndexedSeq(fakeSelf), + spendingTransaction = ErgoLikeTransactionTesting.dummy, + self = fakeSelf, + activatedVersionInTests) proverB.prove(env, prop2, ctxf2, fakeMessage).isSuccess shouldBe false //Successful run below: @@ -126,7 +130,8 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, + activatedVersionInTests) val pr = proverA.prove(env, prop2, ctx1, fakeMessage).get verifier.verify(env, prop2, ctx1, pr, fakeMessage).get._1 shouldBe true @@ -141,7 +146,8 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fakeSelf), spendingTransaction = ErgoLikeTransactionTesting.dummy, - self = fakeSelf) + self = fakeSelf, + activatedVersionInTests) val pr2 = proverB2.prove(env, prop1, ctx2, fakeMessage).get verifier.verify(env, prop1, ctx2, pr2, fakeMessage).get._1 shouldBe true diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala index 31251cbb93..3907f57ea5 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala @@ -138,7 +138,7 @@ block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661 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 genesisState = ValidationState.initialState(activatedVersionInTests, initBlock) val fromState = genesisState.boxesReader.byId(genesisState.boxesReader.allIds.head).get val initialBox = new ErgoBox(initialBoxCandidate.value, initialBoxCandidate.ergoTree, initialBoxCandidate.additionalTokens, initialBoxCandidate.additionalRegisters, @@ -173,6 +173,7 @@ block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661 IndexedSeq(emissionBox), ut, emissionBox, + activatedVersionInTests, ContextExtension.empty) val proverResult = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, context, ut.messageToSign).get ut.toSigned(IndexedSeq(proverResult)) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala index fa03a9904d..3950f74f03 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala @@ -134,7 +134,8 @@ class ColdWalletAdvContractExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = firstWithdrawTx1Key, - self = depositOutput + self = depositOutput, + activatedVersionInTests ) val verifier = new ErgoLikeTestInterpreter @@ -170,7 +171,8 @@ class ColdWalletAdvContractExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = firstWithdrawTx2Key, - self = depositOutput + self = depositOutput, + activatedVersionInTests ) val proofAliceBobWithdraw = alice.withSecrets(bob.dlogSecrets).prove(spendEnv, script, firstWithdrawContext2Key, fakeMessage).get.proof diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala index 3987f84dfd..c7d5bd4caf 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala @@ -100,7 +100,8 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTxAliceAndBob, - self = depositOutput + self = depositOutput, + activatedVersionInTests ) val proofAliceAndBobWithdraw = alice.withSecrets(bob.dlogSecrets).prove(spendEnv, script, withdrawContextAliceandBob, fakeMessage).get.proof @@ -130,7 +131,8 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = firstWithdrawTx, - self = depositOutput + self = depositOutput, + activatedVersionInTests ) val proofAliceWithdraw = alice.prove(spendEnv, script, firstWithdrawContext, fakeMessage).get.proof @@ -159,7 +161,8 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTxInvalid, - self = depositOutput + self = depositOutput, + activatedVersionInTests ) an [AssertionError] should be thrownBy ( @@ -193,7 +196,8 @@ class ColdWalletContractExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(firstChangeOutput), spendingTransaction = secondWithdrawTx, - self = firstChangeOutput + self = firstChangeOutput, + activatedVersionInTests ) val proofAliceSecondWithdraw = alice.prove(spendEnv, script, secondWithdrawContext, fakeMessage).get.proof diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala index c44e5acb35..263d3336f7 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala @@ -27,7 +27,7 @@ class CoopExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(self), spendingTransaction = tx, - self = self) + self = self, activatedVersionInTests) } def successProofTest(exp: SigmaPropValue, diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala index 7d6382ad34..ca56e7b3cf 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala @@ -84,7 +84,7 @@ class DHTupleExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(inBox), spendingTransaction = tx, - self = inBox + self = inBox, activatedVersionInTests ) val dhtBob = DiffieHellmanTupleProverInput(y, ProveDHTuple(g, g_x, g_y, 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 f8f7edd717..1eb9c9a930 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala @@ -91,7 +91,7 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx1, - self = selfBox, + self = selfBox, activatedVersionInTests, extension = ce) //user can spend all the money @@ -111,7 +111,7 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx2, - self = selfBox, + self = selfBox, activatedVersionInTests, extension = ce) //user can spend all the money @@ -127,7 +127,7 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(b, selfBox), spendingTransaction = tx3, - self = selfBox) + self = selfBox, activatedVersionInTests) assert(ctx3.spendingTransaction.outputs.head.propositionBytes sameElements ctx3.boxesToSpend(ctx3.selfIndex).propositionBytes) @@ -144,7 +144,7 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(b2, selfBox), spendingTransaction = tx4, - self = selfBox, + self = selfBox, activatedVersionInTests, extension = ce) minerProver.prove(prop, ctx4, fakeMessage).isSuccess shouldBe false @@ -159,7 +159,7 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), spendingTransaction = tx5, - self = selfBox, + self = selfBox, activatedVersionInTests, extension = ce) val mProof2 = minerProver.prove(prop, ctx5, fakeMessage).get @@ -176,7 +176,7 @@ class DemurrageExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(b3, selfBox6), spendingTransaction = tx6, - self = selfBox6, + self = selfBox6, activatedVersionInTests, extension = ce) val mProof3 = minerProver.prove(prop, ctx6, fakeMessage).get diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala index d24fe63bed..7d9eec20e4 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala @@ -150,7 +150,7 @@ class FsmExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox1), createTransaction(fsmBox2), - self = fsmBox1) + self = fsmBox1, activatedVersionInTests) val spendingProof = prover .withContextExtender(scriptVarId, ByteArrayConstant(ValueSerializer.serialize(script1))) @@ -170,7 +170,7 @@ class FsmExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox2), createTransaction(fsmBox1), - self = fsmBox2) + self = fsmBox2, activatedVersionInTests) val spendingProof2 = prover .withContextExtender(scriptVarId, ByteArrayConstant(ValueSerializer.serialize(script2))) @@ -198,7 +198,7 @@ class FsmExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox1), createTransaction(fsmBox3), - self = fsmBox1) + self = fsmBox1, activatedVersionInTests) //honest prover fails prover @@ -225,7 +225,7 @@ class FsmExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox2), createTransaction(fsmBox3), - self = fsmBox2) + self = fsmBox2, activatedVersionInTests) val spendingProof23 = prover .withContextExtender(scriptVarId, ByteArrayConstant(ValueSerializer.serialize(script3))) @@ -247,7 +247,7 @@ class FsmExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox3), createTransaction(freeBox), - self = fsmBox3) + self = fsmBox3, activatedVersionInTests) val spendingProof30 = prover .withContextExtender(scriptVarId, ByteArrayConstant(ValueSerializer.serialize(script4))) @@ -263,7 +263,7 @@ class FsmExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fsmBox2), createTransaction(freeBox), - self = fsmBox2) + self = fsmBox2, activatedVersionInTests) //honest prover fails prover diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala index b38726f016..f73420fb2a 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala @@ -414,7 +414,7 @@ class IcoExample extends SigmaTestingCommons { suite => minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = inputBoxes, spendingTransaction = fundingTx, - self = projectBoxBefore) + self = projectBoxBefore, activatedVersionInTests) val projectProver = new ContextEnrichingTestProvingInterpreter() .withContextExtender(1, ByteArrayConstant(proof)) @@ -451,7 +451,7 @@ class IcoExample extends SigmaTestingCommons { suite => minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(projectBoxBeforeClosing), spendingTransaction = issuanceTx, - self = projectBoxBeforeClosing) + self = projectBoxBeforeClosing, activatedVersionInTests) val res = project.prove(env, issuanceScript, issuanceContext, fakeMessage).get println("token issuance script cost: " + res.cost) @@ -523,7 +523,7 @@ class IcoExample extends SigmaTestingCommons { suite => minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(projectBoxBefore), spendingTransaction = fundingTx, - self = projectBoxBefore) + self = projectBoxBefore, activatedVersionInTests) val projectProver = new ContextEnrichingTestProvingInterpreter() diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala index 97746d4381..0350a0576e 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala @@ -308,7 +308,7 @@ class LetsSpecification extends SigmaTestingCommons { suite => minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(projectBoxBefore), spendingTransaction = issuanceTx, - self = projectBoxBefore) + self = projectBoxBefore, activatedVersionInTests) val managementProver = new ContextEnrichingTestProvingInterpreter() .withContextExtender(1, ByteArrayConstant(proof)) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala index a66e50993c..6f2d22b75e 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala @@ -55,7 +55,7 @@ class MASTExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(input1), tx, - self = input1) + self = input1, activatedVersionInTests) val prover = new ContextEnrichingTestProvingInterpreter() @@ -109,7 +109,7 @@ class MASTExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), createTransaction(testBox(1, recipientProposition, 0)), - self = selfBox) + self = selfBox, activatedVersionInTests) avlProver.performOneOperation(Lookup(knownSecretTreeKey)) val knownSecretPathProof = avlProver.generateProof() diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala index 507f8bb10d..72bdae29a7 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala @@ -162,7 +162,7 @@ class MixExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(halfMixOutput), spendingTransaction = fullMixTx, - self = halfMixOutput + self = halfMixOutput, activatedVersionInTests ) // bob (2nd player) is generating a proof and it is passing verification @@ -217,7 +217,7 @@ class MixExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(aliceAnonBox), spendingTransaction = spendingTx, - self = aliceAnonBox + self = aliceAnonBox, activatedVersionInTests ) // To Do: Extract below g_y, g_xy from fullMixOutputs registers @@ -239,7 +239,7 @@ class MixExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(bobAnonBox), spendingTransaction = spendingTx, - self = bobAnonBox + self = bobAnonBox, activatedVersionInTests ) val proofBobSpend = bob.prove(fullMixEnv, fullMixScript, bobSpendContext, fakeMessage).get.proof diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala index edaf3cc23b..6cc1486caa 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala @@ -179,7 +179,7 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(sAlice, sBob), spendingTransaction, - self = sAlice) + self = sAlice, activatedVersionInTests) val alice = aliceTemplate .withContextExtender(22: Byte, BoxConstant(oracleBox)) @@ -256,7 +256,7 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(sOracle, sAlice, sBob), spendingTransaction, - self = sOracle) + self = sOracle, activatedVersionInTests) val prA = alice.prove(emptyEnv + (ScriptNameProp -> "alice_prove"), prop, ctx, fakeMessage).get verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, prA, fakeMessage).get._1 shouldBe true diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala index 2679ab1aa1..93ee3c595d 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala @@ -160,7 +160,8 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(halfGameOutput), spendingTransaction = fullGameTx, - self = halfGameOutput // what is the use of self? + self = halfGameOutput, // what is the use of self? + activatedVersionInTests ) // bob (2nd player) is generating a proof and it is passing verification @@ -196,7 +197,7 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0, fullGameOutput1), spendingTransaction = gameOverTx, - self = fullGameOutput0 + self = fullGameOutput0, activatedVersionInTests ) val winContext1 = ErgoLikeContextTesting( @@ -205,7 +206,7 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0, fullGameOutput1), spendingTransaction = gameOverTx, - self = fullGameOutput1 + self = fullGameOutput1, activatedVersionInTests ) a - b match { @@ -221,7 +222,7 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0), spendingTransaction = gameOverTx, - self = fullGameOutput0 + self = fullGameOutput0, activatedVersionInTests ) val proofAliceDraw = aliceProver.prove(fullGameEnv, fullGameScript, drawContextAlice, fakeMessage).get @@ -233,7 +234,7 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput1), spendingTransaction = gameOverTx, - self = fullGameOutput1 + self = fullGameOutput1, activatedVersionInTests ) val proofBobDraw = bobProver.prove(fullGameEnv, fullGameScript, drawContextBob, fakeMessage).get @@ -282,7 +283,8 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0, fullGameOutput1), spendingTransaction = defaultWinTx, - self = fullGameOutput0 // what is the use of self? + self = fullGameOutput0, // what is the use of self? + activatedVersionInTests ) val defaultWinContext1 = ErgoLikeContextTesting( currentHeight = defaultWinHeight, @@ -290,7 +292,8 @@ class RPSGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput0, fullGameOutput1), spendingTransaction = defaultWinTx, - self = fullGameOutput1 // what is the use of self? + self = fullGameOutput1, // what is the use of self? + activatedVersionInTests ) val sDummy = Array[Byte]() // empty value for s; commitment cannot be opened but still Bob will be able to spend diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala index 60a07f4999..cce59488b0 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala @@ -150,7 +150,7 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTx, - self = depositOutput + self = depositOutput, activatedVersionInTests ) val proofWithdraw = alice.prove(depositEnv, depositScript, withdrawContext, fakeMessage).get.proof @@ -179,7 +179,7 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(reversibleWithdrawOutput), spendingTransaction = bobSpendTx, - self = reversibleWithdrawOutput + self = reversibleWithdrawOutput, activatedVersionInTests ) val spendEnv = Map(ScriptNameProp -> "spendEnv") @@ -206,7 +206,7 @@ class ReversibleTxExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(reversibleWithdrawOutput), spendingTransaction = carolSpendTx, - self = reversibleWithdrawOutput + self = reversibleWithdrawOutput, activatedVersionInTests ) val proofCarolSpend = carol.prove(spendEnv, withdrawScript, carolSpendContext, fakeMessage).get.proof diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala index ae80e4311d..f4716046d8 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala @@ -62,7 +62,7 @@ class Rule110Specification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(input), tx, - self = input).withCostLimit(maxCost) + self = input, activatedVersionInTests).withCostLimit(maxCost) val pr = prover.prove(prop, ctx, fakeMessage).get verifier.verify(prop, ctx, pr, fakeMessage).get._1 shouldBe true @@ -224,7 +224,7 @@ class Rule110Specification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(nIn0, nIn1, nIn2), nTx, - self = nIn0) + self = nIn0, activatedVersionInTests) val nProof = nProver.prove(prop, nCtx, fakeMessage).get verifier.verify(prop, nCtx, nProof, fakeMessage).get._1 shouldBe true @@ -246,7 +246,7 @@ class Rule110Specification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(rIn0, rIn1), rTx, - self = rIn0) + self = rIn0, activatedVersionInTests) val rProof = rProver.prove(prop, rCtx, fakeMessage).get verifier.verify(prop, rCtx, rProof, fakeMessage).get._1 shouldBe true @@ -268,7 +268,7 @@ class Rule110Specification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(lnIn0, lnIn1), lnTx, - self = lnIn0) + self = lnIn0, activatedVersionInTests) val lnProof = lnProver.prove(prop, lnCtx, fakeMessage).get verifier.verify(prop, lnCtx, lnProof, fakeMessage).get._1 shouldBe true @@ -289,7 +289,7 @@ class Rule110Specification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(lIn0), lTx, - self = lIn0) + self = lIn0, activatedVersionInTests) val lProof = lProver.prove(prop, lCtx, fakeMessage).get verifier.verify(prop, lCtx, lProof, fakeMessage).get._1 shouldBe true @@ -409,7 +409,7 @@ class Rule110Specification extends SigmaTestingCommons { ErgoLikeContextTesting.dummyPubkey ) - val genesisState = ValidationState.initialState(initBlock) + val genesisState = ValidationState.initialState(activatedVersionInTests, initBlock) def byPos(state: ValidationState, row: Int, pos: Int) = state.boxesReader.byTwoInts(RowReg, row, ColumnReg, pos).get @@ -445,6 +445,7 @@ class Rule110Specification extends SigmaTestingCommons { IndexedSeq(left, center, right), ut, left, + activatedVersionInTests, ContextExtension.empty) val proverResultLeft = prover.prove(left.ergoTree, contextLeft, ut.messageToSign).get @@ -454,6 +455,7 @@ class Rule110Specification extends SigmaTestingCommons { IndexedSeq(left, center, right), ut, center, + activatedVersionInTests, ContextExtension.empty) val proverResultCenter = prover.prove(center.ergoTree, contextCenter, ut.messageToSign).get @@ -463,6 +465,7 @@ class Rule110Specification extends SigmaTestingCommons { IndexedSeq(left, center, right), ut, right, + activatedVersionInTests, ContextExtension.empty) val proverResultRight = prover.prove(right.ergoTree, contextRight, ut.messageToSign).get ut.toSigned(IndexedSeq(proverResultLeft, proverResultCenter, proverResultRight)) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala index ad0e561324..d44ab41bae 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala @@ -63,7 +63,8 @@ class TimedPaymentExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTx, - self = depositOutput + self = depositOutput, + activatedVersionInTests ) val proofWithdraw = alice.withContextExtender( @@ -80,7 +81,8 @@ class TimedPaymentExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(depositOutput), spendingTransaction = withdrawTx, - self = depositOutput + self = depositOutput, + activatedVersionInTests ) an [InterpreterException] should be thrownBy (alice.withContextExtender( 1, IntConstant(confDeadline - 20) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala index 46d67b19d3..d7e46e5251 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala @@ -149,7 +149,8 @@ class XorGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(halfGameOutput), spendingTransaction = abortHalfGameTx, - self = halfGameOutput // what is the use of self? + self = halfGameOutput, // what is the use of self? + activatedVersionInTests ) val proofAbortHalfGame = alice.prove(halfGameEnv, halfGameScript, abortHalfGameContext, fakeMessage).get.proof @@ -185,7 +186,8 @@ class XorGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(halfGameOutput), spendingTransaction = fullGameTx, - self = halfGameOutput // what is the use of self? + self = halfGameOutput, // what is the use of self? + activatedVersionInTests ) // bob (2nd player) is generating a proof and it is passing verification @@ -235,7 +237,8 @@ class XorGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput), spendingTransaction = gameOverTx, - self = fullGameOutput // what is the use of self? + self = fullGameOutput, // what is the use of self? + activatedVersionInTests ) val proofGameOver = winner.prove(fullGameEnv, fullGameScript, gameOverContext, fakeMessage).get @@ -262,7 +265,8 @@ class XorGameExampleSpecification extends SigmaTestingCommons { minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(fullGameOutput), spendingTransaction = defaultWinTx, - self = fullGameOutput // what is the use of self? + self = fullGameOutput, // what is the use of self? + activatedVersionInTests ) val sDummy = Array[Byte]() // empty value for s; commitment cannot be opened but still Bob will be able to spend diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala index cc7ce5f4b0..a5ad065d45 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslSpecification.scala @@ -40,7 +40,7 @@ import scala.collection.mutable /** This suite tests every method of every SigmaDsl type to be equivalent to * the evaluation of the corresponding ErgoScript operation */ -class SigmaDslSpecification extends SigmaDslTesting { suite => +class SigmaDslSpecification extends SigmaDslTesting with CrossVersionProps { suite => override implicit val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 30) diff --git a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala index f583e9bfc9..580f9cd7c1 100644 --- a/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala +++ b/sigmastate/src/test/scala/special/sigma/SigmaDslTesting.scala @@ -335,7 +335,8 @@ class SigmaDslTesting extends PropSpec case _ => ErgoLikeContextTesting.dummy( - createBox(0, compiledTree, additionalRegisters = newRegisters) + createBox(0, compiledTree, additionalRegisters = newRegisters), + activatedVersionInTests ).withBindings( 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA), 2.toByte -> ByteArrayConstant(pkCarolBytes) From dd1e0530de3704c9114e400d6cddceed2e8d5c95 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 21 Dec 2020 19:05:04 +0300 Subject: [PATCH 26/31] versioned-tests: passing activatedVersionInTests to test contexts (part 2) --- .../org/ergoplatform/dsl/TestContractSpec.scala | 3 ++- .../helpers/ErgoLikeContextTesting.scala | 14 ++++++++------ .../utxo/examples/LetsSpecification.scala | 3 ++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index b63e9dbf3d..cccf35a72a 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -84,7 +84,8 @@ case class TestContractSpec(testSuite: SigmaTestingCommons)(implicit val IR: IRC dataBoxes = dataBoxes, boxesToSpend = boxesToSpend, spendingTransaction = createTransaction(dataBoxes, tx.outputs.map(_.ergoBox).toIndexedSeq), - selfIndex = boxesToSpend.indexOf(utxoBox.ergoBox) ) + selfIndex = boxesToSpend.indexOf(utxoBox.ergoBox), + activatedVersion = testSuite.activatedVersionInTests) ctx } def runDsl(extensions: Map[Byte, AnyValue] = Map()): SigmaProp = { diff --git a/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala index af409d7b50..2ddd47e30b 100644 --- a/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala +++ b/sigmastate/src/test/scala/sigmastate/helpers/ErgoLikeContextTesting.scala @@ -55,18 +55,20 @@ object ErgoLikeContextTesting { dataBoxes: IndexedSeq[ErgoBox], boxesToSpend: IndexedSeq[ErgoBox], spendingTransaction: ErgoLikeTransactionTemplate[_ <: UnsignedInput], - selfIndex: Int) = + selfIndex: Int, + activatedVersion: Byte) = new ErgoLikeContext( lastBlockUtxoRoot, noHeaders, dummyPreHeader(currentHeight, minerPubkey), dataBoxes, boxesToSpend, spendingTransaction, selfIndex, ContextExtension.empty, ValidationRules.currentSettings, ScriptCostLimit.value, - initCost = 0L, Interpreter.MaxSupportedScriptVersion) + initCost = 0L, activatedVersion) - def dummy(selfDesc: ErgoBox, activatedVersion: Byte): ErgoLikeContext = ErgoLikeContextTesting(currentHeight = 0, - lastBlockUtxoRoot = AvlTreeData.dummy, dummyPubkey, boxesToSpend = IndexedSeq(selfDesc), - spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), self = selfDesc, - activatedVersion = activatedVersion) + def dummy(selfDesc: ErgoBox, activatedVersion: Byte): ErgoLikeContext = + ErgoLikeContextTesting(currentHeight = 0, + lastBlockUtxoRoot = AvlTreeData.dummy, dummyPubkey, boxesToSpend = IndexedSeq(selfDesc), + spendingTransaction = ErgoLikeTransaction(IndexedSeq(), IndexedSeq()), self = selfDesc, + activatedVersion = activatedVersion) val noInputs: Array[Box] = Array[Box]() val noOutputs: Array[Box] = Array[Box]() diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala index 0350a0576e..9872956dd3 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala @@ -356,7 +356,8 @@ class LetsSpecification extends SigmaTestingCommons { suite => dataBoxes = IndexedSeq(directoryBox), boxesToSpend = IndexedSeq(userBoxBefore0, userBoxBefore1), spendingTransaction = issuanceTx, - selfIndex = 0) + selfIndex = 0, + activatedVersionInTests) val managementProver = new ContextEnrichingTestProvingInterpreter() .withContextExtender(1, ByteArrayConstant(proof)) From 0b3040b2b647c19d08e196c8fe045c1a2b6c7fc0 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 21 Dec 2020 21:52:15 +0300 Subject: [PATCH 27/31] versioned-tests: passing activatedVersionInTests to test contexts (part 3) --- .travis.jvmopts | 2 +- .../ergoplatform/ErgoAddressSpecification.scala | 5 +++-- .../org/ergoplatform/ErgoScriptPredefSpec.scala | 2 +- .../sigmastate/CalcSha256Specification.scala | 4 ++-- .../scala/sigmastate/FailingToProveSpec.scala | 3 ++- .../ScriptVersionSwitchSpecification.scala | 15 ++++++++------- .../SoftForkabilitySpecification.scala | 3 ++- .../TestingInterpreterSpecification.scala | 3 ++- .../DeserializationResilience.scala | 2 +- .../SigSerializerSpecification.scala | 3 ++- .../utxo/AVLTreeScriptsSpecification.scala | 3 ++- .../sigmastate/utxo/BasicOpsSpecification.scala | 3 ++- .../utxo/BlockchainSimulationSpecification.scala | 15 ++++++++------- .../utxo/CollectionOperationsSpecification.scala | 3 ++- .../utxo/ComplexSigSpecification.scala | 3 ++- .../utxo/ContextEnrichingSpecification.scala | 4 ++-- .../utxo/DistributedSigSpecification.scala | 16 +++++++++++----- .../utxo/ErgoLikeInterpreterSpecification.scala | 3 ++- .../sigmastate/utxo/SpamSpecification.scala | 0 .../sigmastate/utxo/ThresholdSpecification.scala | 1 - .../UsingContextPropertiesSpecification.scala | 5 +++-- .../BlockchainSimulationSpecification.scala | 10 +++++----- .../examples/CoinEmissionSpecification.scala | 3 ++- ...ldWalletAdvContractExampleSpecification.scala | 11 ++++++----- .../ColdWalletContractExampleSpecification.scala | 9 +++++---- .../utxo/examples/CoopExampleSpecification.scala | 7 ++++--- .../examples/DHTupleExampleSpecification.scala | 9 +++++---- .../examples/DemurrageExampleSpecification.scala | 3 ++- .../utxo/examples/FsmExampleSpecification.scala | 3 ++- .../sigmastate/utxo/examples/IcoExample.scala | 3 ++- .../utxo/examples/LetsSpecification.scala | 10 +++++----- .../utxo/examples/MASTExampleSpecification.scala | 3 ++- .../utxo/examples/MixExampleSpecification.scala | 9 +++++---- .../examples/OracleExamplesSpecification.scala | 3 ++- .../examples/RPSGameExampleSpecification.scala | 3 ++- .../ReversibleTxExampleSpecification.scala | 3 ++- .../utxo/examples/Rule110Specification.scala | 3 ++- .../TimedPaymentExampleSpecification.scala | 3 ++- .../examples/XorGameExampleSpecification.scala | 3 ++- 39 files changed, 115 insertions(+), 81 deletions(-) delete mode 100644 sigmastate/src/test/scala/sigmastate/utxo/SpamSpecification.scala diff --git a/.travis.jvmopts b/.travis.jvmopts index 3d4461e517..2e608cfbfd 100644 --- a/.travis.jvmopts +++ b/.travis.jvmopts @@ -1,4 +1,4 @@ --Xmx4g +-Xmx6g -Xss2m -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala index 10a61f9a4b..3db081079f 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala @@ -11,7 +11,7 @@ import sigmastate.basics.DLogProtocol.DLogProverInput import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer import sigmastate.serialization.ValueSerializer import scorex.util.encode.Base58 -import sigmastate.{SigmaAnd, SType} +import sigmastate.{SigmaAnd, SType, CrossVersionProps} import sigmastate.Values.{UnparsedErgoTree, Constant, EvaluatedValue, ByteArrayConstant, IntConstant, ErgoTree} import sigmastate.eval.IRContext import sigmastate.helpers._ @@ -23,7 +23,8 @@ import sigmastate.lang.exceptions.{CosterException, CostLimitException} import sigmastate.utils.Helpers._ import special.sigma.SigmaDslTesting -class ErgoAddressSpecification extends SigmaDslTesting with TryValues { +class ErgoAddressSpecification extends SigmaDslTesting + with TryValues with CrossVersionProps { private implicit val ergoAddressEncoder: ErgoAddressEncoder = new ErgoAddressEncoder(TestnetNetworkPrefix) diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala index 0e5c1291e7..a3b099b478 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala @@ -23,7 +23,7 @@ import sigmastate.utils.Helpers._ import scala.util.Try -class ErgoScriptPredefSpec extends SigmaTestingCommons { +class ErgoScriptPredefSpec extends SigmaTestingCommons with CrossVersionProps { private implicit lazy val IR: TestingIRContext = new TestingIRContext { override val okPrintEvaluatedEntries: Boolean = false } diff --git a/sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala b/sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala index 2e1efcf7b1..7062c0153a 100644 --- a/sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala +++ b/sigmastate/src/test/scala/sigmastate/CalcSha256Specification.scala @@ -1,12 +1,12 @@ package sigmastate -import org.ergoplatform.ErgoLikeContext import org.scalatest.prop.TableFor2 import scorex.util.encode.Base16 import sigmastate.Values.{ByteArrayConstant, CollectionConstant} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons} -class CalcSha256Specification extends SigmaTestingCommons { +class CalcSha256Specification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext def stringToByteConstant(in: String): CollectionConstant[SByte.type] = ByteArrayConstant(in.getBytes("UTF-8")) diff --git a/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala b/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala index 753937abf8..53a94af830 100644 --- a/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala +++ b/sigmastate/src/test/scala/sigmastate/FailingToProveSpec.scala @@ -7,7 +7,8 @@ import org.scalatest.TryValues._ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import org.ergoplatform.ErgoScriptPredef._ -class FailingToProveSpec extends SigmaTestingCommons { +class FailingToProveSpec extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext /** * Both properties should work fine. diff --git a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index f80f9899ec..f8dd8a3a8e 100644 --- a/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -19,7 +19,8 @@ import sigmastate.helpers.TestingHelpers._ import scala.util.Success /** Specification to verify that the interpreter behaves according to docs/aot-jit-switch.md. */ -class ScriptVersionSwitchSpecification extends SigmaDslTesting { +class ScriptVersionSwitchSpecification extends SigmaDslTesting + with CrossVersionProps { override implicit val generatorDrivenConfig = PropertyCheckConfiguration(minSuccessful = 30) implicit def IR = createIR() @@ -69,12 +70,12 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { ErgoBox.R4 -> Constant[SType](Coll[Box]().asInstanceOf[SType#WrappedType], tpeA) ) - val ctx = copyContext(ErgoLikeContextTesting.dummy( + val ctx = ErgoLikeContextTesting.dummy( createBox(0, ergoTree, additionalRegisters = newRegisters), - activatedVersionInTests + activatedScriptVersion ).withBindings( 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA) - ).asInstanceOf[ErgoLikeContext])(activatedScriptVersion = activatedScriptVersion) + ).asInstanceOf[ErgoLikeContext] val prover = new FeatureProvingInterpreter() val pr = prover.prove(ergoTree, ctx, fakeMessage).getOrThrow pr @@ -87,12 +88,12 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { ErgoBox.R4 -> Constant[SType](Coll[Box]().asInstanceOf[SType#WrappedType], tpeA) ) - val ctx = copyContext(ErgoLikeContextTesting.dummy( + val ctx = ErgoLikeContextTesting.dummy( createBox(0, ergoTree, additionalRegisters = newRegisters), - activatedVersionInTests + activatedScriptVersion ).withBindings( 1.toByte -> Constant[SType](input.asInstanceOf[SType#WrappedType], tpeA) - ).asInstanceOf[ErgoLikeContext])(activatedScriptVersion = activatedScriptVersion) + ).asInstanceOf[ErgoLikeContext] val verifier = new ErgoLikeInterpreter() { type CTX = ErgoLikeContext } val pr = ProverResult(ProverResult.empty.proof, ctx.extension) diff --git a/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index 02469a1db7..9af961b0db 100644 --- a/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -19,7 +19,8 @@ import sigmastate.utxo.{DeserializeContext, SelectField} import special.sigma.SigmaTestingData import sigmastate.utils.Helpers._ -class SoftForkabilitySpecification extends SigmaTestingData { +class SoftForkabilitySpecification extends SigmaTestingData + with CrossVersionProps { implicit lazy val IR = new TestingIRContext lazy val prover = new ErgoLikeTestProvingInterpreter() diff --git a/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index eb9364102b..0c58b52a5a 100644 --- a/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -17,7 +17,8 @@ import sigmastate.utils.Helpers._ import scala.util.Random -class TestingInterpreterSpecification extends SigmaTestingCommons { +class TestingInterpreterSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext lazy val prover = new ErgoLikeTestProvingInterpreter() lazy val verifier = new ErgoLikeTestInterpreter diff --git a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala index 4f42356699..a368f579b0 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala @@ -24,7 +24,7 @@ import sigmastate.utils.Helpers._ import scala.collection.mutable class DeserializationResilience extends SerializationSpecification - with SigmaTestingCommons { + with SigmaTestingCommons with CrossVersionProps { implicit lazy val IR: TestingIRContext = new TestingIRContext { // substFromCostTable = false diff --git a/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala index def72b52ed..6adcd7a662 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/SigSerializerSpecification.scala @@ -15,7 +15,8 @@ import sigmastate.utxo.Transformer import scala.util.Random -class SigSerializerSpecification extends SigmaTestingCommons with ObjectGenerators { +class SigSerializerSpecification extends SigmaTestingCommons + with ObjectGenerators with CrossVersionProps { implicit lazy val IR = new TestingIRContext private lazy implicit val arbExprGen: Arbitrary[SigmaBoolean] = Arbitrary(exprTreeGen) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala index dadaac6451..044c0e5777 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala @@ -22,7 +22,8 @@ import special.collection.Coll import special.sigma.{AvlTree, Context} -class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => +class AVLTreeScriptsSpecification extends SigmaTestingCommons + with CrossVersionProps { suite => import org.ergoplatform.dsl.AvlTreeHelpers._ lazy val spec = TestContractSpec(suite)(new TestingIRContext) lazy val prover = spec.ProvingParty("Alice") diff --git a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index d73788547d..34c948cd49 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -18,7 +18,8 @@ import SType.AnyOps import sigmastate.interpreter.CryptoConstants import sigmastate.utils.Helpers._ -class BasicOpsSpecification extends SigmaTestingCommons { +class BasicOpsSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext { override val okPrintEvaluatedEntries: Boolean = false } diff --git a/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala index c91bcd997b..a3a071a341 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/BlockchainSimulationSpecification.scala @@ -1,22 +1,22 @@ package sigmastate.utxo -import java.io.{File, FileWriter} +import java.io.{FileWriter, File} import org.ergoplatform import org.ergoplatform.ErgoBox.TokenId import org.ergoplatform._ import org.scalacheck.Gen -import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Remove} +import scorex.crypto.authds.avltree.batch.{Remove, BatchAVLProver, Insert} import scorex.crypto.authds.{ADDigest, ADKey, ADValue} -import scorex.crypto.hash.{Blake2b256, Digest32} +import scorex.crypto.hash.{Digest32, Blake2b256} import scorex.util._ -import sigmastate.Values.{IntConstant, LongConstant} -import sigmastate.helpers.{BlockchainState, ErgoLikeContextTesting, ErgoLikeTestProvingInterpreter, ErgoTransactionValidator, SigmaTestingCommons} +import sigmastate.Values.{LongConstant, IntConstant} +import sigmastate.helpers.{ErgoTransactionValidator, ErgoLikeContextTesting, ErgoLikeTestProvingInterpreter, SigmaTestingCommons, BlockchainState} import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.ContextExtension import sigmastate.eval._ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} -import sigmastate.{AvlTreeData, AvlTreeFlags, GE} +import sigmastate.{GE, AvlTreeData, AvlTreeFlags, CrossVersionProps} import scala.annotation.tailrec import scala.collection.concurrent.TrieMap @@ -24,7 +24,8 @@ import scala.collection.mutable import scala.util.Try -class BlockchainSimulationSpecification extends SigmaTestingCommons { +class BlockchainSimulationSpecification extends SigmaTestingCommons + with CrossVersionProps { import BlockchainSimulationSpecification._ implicit lazy val IR = new TestingIRContext diff --git a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala index ad86946261..5293ef0b59 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala @@ -12,7 +12,8 @@ import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.serialization.OpCodes._ import sigmastate.utils.Helpers._ -class CollectionOperationsSpecification extends SigmaTestingCommons { +class CollectionOperationsSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR: TestingIRContext = new TestingIRContext private val reg1 = ErgoBox.nonMandatoryRegisters.head diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala index 7ad3cd5fbf..a12b41e10e 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ComplexSigSpecification.scala @@ -9,7 +9,8 @@ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeConte import scala.util.Random -class ComplexSigSpecification extends SigmaTestingCommons { +class ComplexSigSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR: TestingIRContext = new TestingIRContext private def proverGen: Gen[ContextEnrichingTestProvingInterpreter] = for { diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala index 045c9cc4b5..b073d0f8ab 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ContextEnrichingSpecification.scala @@ -1,6 +1,5 @@ package sigmastate.utxo -import org.ergoplatform.ErgoLikeContext import scorex.util.encode.Base16 import scorex.crypto.hash.Blake2b256 import sigmastate.Values._ @@ -10,7 +9,8 @@ import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeConte import special.collection.Coll -class ContextEnrichingSpecification extends SigmaTestingCommons { +class ContextEnrichingSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR: TestingIRContext = new TestingIRContext diff --git a/sigmastate/src/test/scala/sigmastate/utxo/DistributedSigSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/DistributedSigSpecification.scala index 21517dd96e..008ce2dd0b 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/DistributedSigSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/DistributedSigSpecification.scala @@ -10,12 +10,11 @@ import sigmastate.lang.Terms._ * See EIP-11 for generic signing procedure. * In some simple generic procedure is simplified. */ -class DistributedSigSpecification extends SigmaTestingCommons { +class DistributedSigSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR: TestingIRContext = new TestingIRContext - private val ctx = fakeContext - /** * An example test where Alice (A) and Bob (B) are signing an input in a distributed way. A statement which * protects the box to spend is "pubkey_Alice && pubkey_Bob". Note that a signature in this case is about @@ -34,6 +33,7 @@ class DistributedSigSpecification extends SigmaTestingCommons { * proof ((a_Alice, a_Bob), e, (z_Alice, z_Bob)). */ property("distributed AND (2 out of 2)") { + val ctx = fakeContext val proverA = new ErgoLikeTestProvingInterpreter val proverB = new ErgoLikeTestProvingInterpreter val verifier: ContextEnrichingTestProvingInterpreter = new ContextEnrichingTestProvingInterpreter @@ -63,6 +63,7 @@ class DistributedSigSpecification extends SigmaTestingCommons { // 3-out-of-3 AND signature property("distributed AND (3 out of 3)") { + val ctx = fakeContext val proverA = new ErgoLikeTestProvingInterpreter val proverB = new ErgoLikeTestProvingInterpreter val proverC = new ErgoLikeTestProvingInterpreter @@ -121,6 +122,7 @@ class DistributedSigSpecification extends SigmaTestingCommons { * He's using his randomness from his first step and completes the (valid) signature. */ property("distributed THRESHOLD - 2 out of 3") { + val ctx = fakeContext val proverA = new ErgoLikeTestProvingInterpreter val proverB = new ErgoLikeTestProvingInterpreter val proverC = new ErgoLikeTestProvingInterpreter @@ -155,6 +157,7 @@ class DistributedSigSpecification extends SigmaTestingCommons { * Distributed threshold signature, 3 out of 4 case. */ property("distributed THRESHOLD - 3 out of 4") { + val ctx = fakeContext val proverA = new ErgoLikeTestProvingInterpreter val proverB = new ErgoLikeTestProvingInterpreter val proverC = new ErgoLikeTestProvingInterpreter @@ -203,6 +206,7 @@ class DistributedSigSpecification extends SigmaTestingCommons { * Distributed threshold signature, 3 out of 4 case, 1 real and 1 simulated secrets are of DH kind. */ property("distributed THRESHOLD - 3 out of 4 - w. DH") { + val ctx = fakeContext val proverA = new ErgoLikeTestProvingInterpreter val proverB = new ErgoLikeTestProvingInterpreter val proverC = new ErgoLikeTestProvingInterpreter @@ -248,7 +252,7 @@ class DistributedSigSpecification extends SigmaTestingCommons { } property("distributed THRESHOLD - 2 out of 5") { - + val ctx = fakeContext val proverA = new ErgoLikeTestProvingInterpreter val proverB = new ErgoLikeTestProvingInterpreter val proverC = new ErgoLikeTestProvingInterpreter @@ -285,7 +289,7 @@ class DistributedSigSpecification extends SigmaTestingCommons { } property("distributed THRESHOLD - 4 out of 8 - DH") { - + val ctx = fakeContext val proverA = new ErgoLikeTestProvingInterpreter val proverB = new ErgoLikeTestProvingInterpreter val proverC = new ErgoLikeTestProvingInterpreter @@ -377,6 +381,7 @@ class DistributedSigSpecification extends SigmaTestingCommons { } property("distributed THRESHOLD - (1-out-of-2) and (1-out-of-2) - DLOG and DH") { + val ctx = fakeContext val proverA = new ErgoLikeTestProvingInterpreter val proverB = new ErgoLikeTestProvingInterpreter val proverC = new ErgoLikeTestProvingInterpreter @@ -419,6 +424,7 @@ class DistributedSigSpecification extends SigmaTestingCommons { property("distributed THRESHOLD mixed via AND") { // atLeast(3, Coll(proveDlog(pkA), proveDlog(pkB), proveDlog(pkC), proveDlog(pkD), proveDlog(pkE))) && (proveDlog(pkB) || proveDlog(pkF)) + val ctx = fakeContext val proverA = new ErgoLikeTestProvingInterpreter val proverB = new ErgoLikeTestProvingInterpreter val proverC = new ErgoLikeTestProvingInterpreter diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala index affba18c96..3ea0bf0058 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala @@ -22,7 +22,8 @@ import sigmastate.serialization.{ValueSerializer, SerializationSpecification} import sigmastate.utils.Helpers._ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons - with SerializationSpecification { + with SerializationSpecification + with CrossVersionProps { implicit lazy val IR: TestingIRContext = new TestingIRContext private val reg1 = ErgoBox.nonMandatoryRegisters.head diff --git a/sigmastate/src/test/scala/sigmastate/utxo/SpamSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/SpamSpecification.scala deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala index c69d4e325f..2f3a2f1059 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala @@ -1,6 +1,5 @@ package sigmastate.utxo -import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction} import sigmastate.basics.DLogProtocol.{DLogProverInput, ProveDlog} import sigmastate.Values.{ConcreteCollection, FalseLeaf, IntConstant, SigmaPropConstant, SigmaPropValue, TrueLeaf} import sigmastate._ diff --git a/sigmastate/src/test/scala/sigmastate/utxo/UsingContextPropertiesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/UsingContextPropertiesSpecification.scala index adde25a799..185be9a713 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/UsingContextPropertiesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/UsingContextPropertiesSpecification.scala @@ -1,6 +1,6 @@ package sigmastate.utxo -import sigmastate.TrivialProp +import sigmastate.{TrivialProp, CrossVersionProps} import sigmastate.eval.{IRContext, CSigmaProp} import sigmastate.eval.Extensions._ import special.sigma.Context @@ -9,7 +9,8 @@ import org.ergoplatform.dsl.{SigmaContractSyntax, ContractSpec, TestContractSpec import org.ergoplatform.ErgoBox import scorex.crypto.hash.Blake2b256 -class UsingContextPropertiesSpecification extends SigmaTestingCommons { suite => +class UsingContextPropertiesSpecification extends SigmaTestingCommons + with CrossVersionProps { suite => lazy val spec = TestContractSpec(suite)(new TestingIRContext) lazy val prover = spec.ProvingParty("Alice") private implicit lazy val IR: IRContext = spec.IR diff --git a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala index 28940cb19e..f3a908e7bf 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationSpecification.scala @@ -1,18 +1,18 @@ package sigmastate.utxo.blockchain -import java.io.{File, FileWriter} +import java.io.{FileWriter, File} -import org.scalacheck.Gen -import sigmastate.Values.{BooleanConstant, ErgoTree, GetVarBoolean, TrueLeaf} +import sigmastate.CrossVersionProps +import sigmastate.Values.{TrueLeaf, GetVarBoolean} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestProvingInterpreter} import sigmastate.interpreter.ContextExtension import sigmastate.utxo.blockchain.BlockchainSimulationTestingCommons._ import scala.collection.concurrent.TrieMap -import scala.util.Random -class BlockchainSimulationSpecification extends BlockchainSimulationTestingCommons { +class BlockchainSimulationSpecification extends BlockchainSimulationTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala index 3907f57ea5..97eee44ab6 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala @@ -20,7 +20,8 @@ import sigmastate.eval._ * This script is corresponding to the whitepaper. Please note that Ergo has different contract * defined in ErgoScriptPredef. */ -class CoinEmissionSpecification extends SigmaTestingCommons with ScorexLogging { +class CoinEmissionSpecification extends SigmaTestingCommons + with ScorexLogging with CrossVersionProps { // don't use TestingIRContext, this suite also serves the purpose of testing the RuntimeIRContext implicit lazy val IR: TestingIRContext = new TestingIRContext { // uncomment if you want to log script evaluation diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala index 3950f74f03..f033d4f6b2 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala @@ -1,16 +1,17 @@ package sigmastate.utxo.examples -import org.ergoplatform.ErgoBox.{R4, R5, R6} +import org.ergoplatform.ErgoBox.{R6, R4, R5} import org.ergoplatform._ -import sigmastate.AvlTreeData -import sigmastate.Values.{IntConstant, LongConstant} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} +import sigmastate.{AvlTreeData, CrossVersionProps} +import sigmastate.Values.{LongConstant, IntConstant} +import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter, SigmaTestingCommons, ContextEnrichingTestProvingInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ -class ColdWalletAdvContractExampleSpecification extends SigmaTestingCommons { +class ColdWalletAdvContractExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { private implicit lazy val IR: TestingIRContext = new TestingIRContext import ErgoAddressEncoder._ diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala index c7d5bd4caf..c0a860abbe 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala @@ -2,15 +2,16 @@ package sigmastate.utxo.examples import org.ergoplatform.ErgoBox.{R4, R5} import org.ergoplatform._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ -import sigmastate.AvlTreeData -import sigmastate.Values.{IntConstant, LongConstant} +import sigmastate.{AvlTreeData, CrossVersionProps} +import sigmastate.Values.{LongConstant, IntConstant} import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ -class ColdWalletContractExampleSpecification extends SigmaTestingCommons { +class ColdWalletContractExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { private implicit lazy val IR: TestingIRContext = new TestingIRContext import ErgoAddressEncoder._ diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala index 263d3336f7..3aa7968d19 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala @@ -5,13 +5,14 @@ import org.scalatest.Assertion import org.scalatest.TryValues._ import sigmastate.basics.DLogProtocol.ProveDlog import scorex.crypto.hash.Blake2b256 -import sigmastate.Values.{ByteArrayConstant, SigmaPropValue, BooleanConstant} +import sigmastate.Values.{ByteArrayConstant, BooleanConstant, SigmaPropValue} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.lang.Terms._ -import sigmastate.AvlTreeData +import sigmastate.{AvlTreeData, CrossVersionProps} -class CoopExampleSpecification extends SigmaTestingCommons { +class CoopExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext def mkTxFromOutputs(ergoBox: ErgoBox*): ErgoLikeTransaction = { diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala index ca56e7b3cf..342aa15cfa 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/DHTupleExampleSpecification.scala @@ -4,17 +4,18 @@ package sigmastate.utxo.examples import java.math.BigInteger import org.ergoplatform.ErgoBox.{R4, R5} -import sigmastate.AvlTreeData +import sigmastate.{AvlTreeData, CrossVersionProps} import sigmastate.Values.GroupElementConstant import sigmastate.basics.DLogProtocol.ProveDlog -import sigmastate.basics.{DiffieHellmanTupleProverInput, ProveDHTuple} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.basics.{ProveDHTuple, DiffieHellmanTupleProverInput} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.CryptoConstants import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ -class DHTupleExampleSpecification extends SigmaTestingCommons { +class DHTupleExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { private implicit lazy val IR = new TestingIRContext /** * let Alice's secret be x and Bob's be y diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala index 1eb9c9a930..838bbf35a8 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/DemurrageExampleSpecification.scala @@ -9,7 +9,8 @@ import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.ContextExtension import sigmastate.lang.Terms._ -class DemurrageExampleSpecification extends SigmaTestingCommons { +class DemurrageExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext /** diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala index 7d9eec20e4..2698231cb3 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala @@ -17,7 +17,8 @@ import sigmastate.serialization.ValueSerializer import sigmastate.utxo._ -class FsmExampleSpecification extends SigmaTestingCommons { +class FsmExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { private implicit lazy val IR: TestingIRContext = new TestingIRContext /** * Similarly to the MAST-like example (in the MASTExampleSpecification class), we can do more complex contracts, diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala index f73420fb2a..eb90bf297a 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/IcoExample.scala @@ -232,7 +232,8 @@ by miners via storage rent mechanism, potentially for decades or even centuries. reasonable to have an additional input from the project with the value equal to the value of the fee output. And so on. */ -class IcoExample extends SigmaTestingCommons { suite => +class IcoExample extends SigmaTestingCommons + with CrossVersionProps { suite => // Not mixed with TestContext since it is not possible to call commpiler.compile outside tests if mixed implicit lazy val IR: IRContext = new IRContext with CompiletimeCosting diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala index 9872956dd3..6d1d0862cc 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/LetsSpecification.scala @@ -3,10 +3,10 @@ package sigmastate.utxo.examples import org.ergoplatform._ import org.ergoplatform.ErgoBox.{R4, R5} import scorex.crypto.authds.{ADKey, ADValue} -import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert, Lookup} -import scorex.crypto.hash.{Blake2b256, Digest32} -import sigmastate.{AvlTreeData, AvlTreeFlags, TrivialProp} -import sigmastate.Values.{AvlTreeConstant, ByteArrayConstant, LongConstant, SigmaPropConstant} +import scorex.crypto.authds.avltree.batch.{Lookup, BatchAVLProver, Insert} +import scorex.crypto.hash.{Digest32, Blake2b256} +import sigmastate.{AvlTreeData, AvlTreeFlags, TrivialProp, CrossVersionProps} +import sigmastate.Values.{ByteArrayConstant, AvlTreeConstant, SigmaPropConstant, LongConstant} import sigmastate.eval.{IRContext, SigmaDsl} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestProvingInterpreter, SigmaTestingCommons} import sigmastate.helpers.TestingHelpers._ @@ -166,7 +166,7 @@ import scala.util.Random some day this article will be continued! */ -class LetsSpecification extends SigmaTestingCommons { suite => +class LetsSpecification extends SigmaTestingCommons with CrossVersionProps { suite => // Not mixed with TestContext since it is not possible to call compiler.compile outside tests if mixed implicit lazy val IR: IRContext = new TestingIRContext diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala index 6f2d22b75e..a2bc75a44b 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala @@ -26,7 +26,8 @@ import scala.util.Random * remain unrevealed, providing more privacy and saving space in a blockchain. * See more at https://bitcointechtalk.com/what-is-a-bitcoin-merklized-abstract-syntax-tree-mast-33fdf2da5e2f */ -class MASTExampleSpecification extends SigmaTestingCommons { +class MASTExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext private val reg1 = ErgoBox.nonMandatoryRegisters.head diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala index 72bdae29a7..1a7f6fb0e4 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala @@ -4,18 +4,19 @@ import java.math.BigInteger import org.ergoplatform.ErgoBox.{R4, R5} import scorex.crypto.hash.Blake2b256 -import sigmastate.AvlTreeData +import sigmastate.{AvlTreeData, CrossVersionProps} import sigmastate.Values.GroupElementConstant import sigmastate.basics.DLogProtocol.ProveDlog -import sigmastate.basics.{DiffieHellmanTupleProverInput, ProveDHTuple} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, SigmaTestingCommons} +import sigmastate.basics.{ProveDHTuple, DiffieHellmanTupleProverInput} +import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, SigmaTestingCommons, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.CryptoConstants import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ import sigmastate.eval._ -class MixExampleSpecification extends SigmaTestingCommons { +class MixExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { private implicit lazy val IR: TestingIRContext = new TestingIRContext property("Evaluation - Mix Example") { diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala index 6cc1486caa..3e0b477302 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala @@ -22,7 +22,8 @@ import sigmastate.utxo._ import special.sigma.Context import sigmastate.utils.Helpers._ -class OracleExamplesSpecification extends SigmaTestingCommons { suite => +class OracleExamplesSpecification extends SigmaTestingCommons + with CrossVersionProps { suite => implicit lazy val IR: TestingIRContext = new TestingIRContext private val reg1 = ErgoBox.nonMandatoryRegisters(0) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala index 93ee3c595d..66a70e4380 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala @@ -12,7 +12,8 @@ import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ -class RPSGameExampleSpecification extends SigmaTestingCommons { +class RPSGameExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext /** RPS game: diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala index cce59488b0..40084dd8ef 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala @@ -11,7 +11,8 @@ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ -class ReversibleTxExampleSpecification extends SigmaTestingCommons { +class ReversibleTxExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { private implicit lazy val IR: TestingIRContext = new TestingIRContext import ErgoAddressEncoder._ diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala index f4716046d8..9619ead6c1 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala @@ -18,7 +18,8 @@ import sigmastate.utxo.blockchain.BlockchainSimulationTestingCommons._ * Wolfram's Rule110 implementations * */ -class Rule110Specification extends SigmaTestingCommons { +class Rule110Specification extends SigmaTestingCommons + with CrossVersionProps { implicit lazy val IR = new TestingIRContext private val reg1 = ErgoBox.nonMandatoryRegisters.head private val reg2 = ErgoBox.nonMandatoryRegisters(1) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala index d44ab41bae..d795f35bef 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala @@ -10,7 +10,8 @@ import sigmastate.lang.Terms._ import sigmastate.lang.exceptions.InterpreterException -class TimedPaymentExampleSpecification extends SigmaTestingCommons { +class TimedPaymentExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { private implicit lazy val IR: TestingIRContext = new TestingIRContext import ErgoAddressEncoder._ diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala index d7e46e5251..b53aa6beb6 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/XorGameExampleSpecification.scala @@ -12,7 +12,8 @@ import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ -class XorGameExampleSpecification extends SigmaTestingCommons { +class XorGameExampleSpecification extends SigmaTestingCommons + with CrossVersionProps { private implicit lazy val IR: TestingIRContext = new TestingIRContext /** XOR game: From 609f76845e53e081458a286e734413c359e686c2 Mon Sep 17 00:00:00 2001 From: Alex Chepurnoy Date: Tue, 22 Dec 2020 21:48:59 +0300 Subject: [PATCH 28/31] unused imports --- .../src/main/scala/sigmastate/interpreter/Interpreter.scala | 2 +- .../main/scala/sigmastate/interpreter/ProverInterpreter.scala | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index e283acb10d..5d380fc9ff 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -10,7 +10,7 @@ import sigmastate.basics.DLogProtocol.{DLogInteractiveProver, FirstDLogProverMes import scorex.util.ScorexLogging import sigmastate.SCollection.SByteArray import sigmastate.Values._ -import sigmastate.eval.{IRContext, Sized, Evaluation} +import sigmastate.eval.{IRContext, Evaluation} import sigmastate.lang.Terms.ValueOps import sigmastate.basics._ import sigmastate.interpreter.Interpreter.{ScriptEnv, VerificationResult} diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index 16a753c9c6..5345d3b799 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -12,7 +12,6 @@ import sigmastate._ import sigmastate.basics.DLogProtocol._ import sigmastate.basics.VerifierMessage.Challenge import sigmastate.basics._ -import sigmastate.lang.exceptions.CostLimitException import sigmastate.utils.Helpers import scala.util.Try From 973f850f0dc2c3758dd7ead29ae77f5e94ef431b Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Wed, 23 Dec 2020 20:23:39 +0200 Subject: [PATCH 29/31] Migrate CI to GA (#710) * add sbt-github-actions plugin, upgrade sbt to 1.4.5; * fix crossScalaVersions; * restore crossScalaVersions for all projects; * remove sbt-github-actions plugin; add publish step to * remove clean.yml; * add tags to ignore (starting with "v"); * combine coverage report generation with test run; * remove tags-ignore; * remove snapshot publishing on Travis; * add COVERALLS_REPO_TOKEN env var; * switch from sbt-git to sbt-dynver for 'version'; * add release.yml workflow; * rename main GA workflow to CI; * run coverageReport under matrix scala version; * remove .travis.yml; split code coverage collection and report uploading; * switch to codecov; * add cache to release.yml workflow; * fix import_gpg.sh permissions, add java version to release.yml; * add required SCM url be Sonatype; * add CONTRIBUTING.md with instructions on how to make a release; * update sbt-sonatype plugin; * fix release.yml step name; * delete .travis.jvmopts; --- .github/workflows/ci.yml | 65 +++++++++++++++++++++++++++++++ .github/workflows/release.yml | 44 +++++++++++++++++++++ .gitignore | 3 +- .travis.yml | 35 ----------------- CONTRIBUTING.md | 4 ++ build.sbt | 42 ++++++-------------- .travis.jvmopts => ci/ci.jvmopts | 0 ci/import_gpg.sh | 21 ++++++++++ ci/pubring.asc | 30 -------------- ci/secring.asc.enc | Bin 3664 -> 0 bytes project/build.properties | 2 +- project/plugins.sbt | 6 +-- 12 files changed, 151 insertions(+), 101 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml delete mode 100644 .travis.yml create mode 100644 CONTRIBUTING.md rename .travis.jvmopts => ci/ci.jvmopts (100%) create mode 100755 ci/import_gpg.sh delete mode 100644 ci/pubring.asc delete mode 100644 ci/secring.asc.enc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..3f87541daf --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,65 @@ +name: CI + +on: + push: + branches: + - master + - develop + pull_request: + types: + - opened + - synchronize + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + build: + name: Test and publish a snapshot + strategy: + matrix: + os: [ubuntu-latest] + scala: [2.12.10, 2.11.12] + java: [adopt@1.11] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout current branch (full) + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Setup Java and Scala + uses: olafurpg/setup-scala@v10 + with: + java-version: ${{ matrix.java }} + + - name: Cache sbt + uses: actions/cache@v2 + with: + path: | + ~/.sbt + ~/.ivy2/cache + ~/.coursier/cache/v1 + ~/.cache/coursier/v1 + ~/AppData/Local/Coursier/Cache/v1 + ~/Library/Caches/Coursier/v1 + key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} + + - name: Runs tests and collect coverage + run: sbt -jvm-opts ci/ci.jvmopts ++${{ matrix.scala }} coverage test coverageReport coverageAggregate + + # - name: Upload coverage report + # run: sbt ++${{ matrix.scala }} coverageReport coverageAggregate coveralls + # env: + # COVERALLS_REPO_TOKEN: $${{ secrets.COVERALLS_REPO_TOKEN }} + + - name: Upload coverage report to Codecov + uses: codecov/codecov-action@v1 + with: + fail_ci_if_error: true + + - name: Publish a snapshot ${{ github.ref }} + run: sbt ++${{ matrix.scala }} publish + env: + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..cb74691dff --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,44 @@ +name: Publish a release + +on: + release: + types: [published] + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +jobs: + publish_release: + name: Publish release to Sonatype + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Setup Java and Scala + uses: olafurpg/setup-scala@v10 + with: + java-version: adopt@1.11 + + - name: Cache sbt + uses: actions/cache@v2 + with: + path: | + ~/.sbt + ~/.ivy2/cache + ~/.coursier/cache/v1 + ~/.cache/coursier/v1 + ~/AppData/Local/Coursier/Cache/v1 + ~/Library/Caches/Coursier/v1 + key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} + + - name: Import GPG key + run: ci/import_gpg.sh + env: + GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} + + - name: Publish release ${{ github.ref }} + run: sbt +publishSigned sonatypeBundleRelease + env: + PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} diff --git a/.gitignore b/.gitignore index 47dc20e13e..d621df577a 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,5 @@ spam-tests/ .bloop/ .metals/ .vscode/ -project/metals.sbt \ No newline at end of file +project/metals.sbt +/project/project/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 002d418bda..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -sudo: required -dist: trusty -before_cache: -- find $HOME/.sbt -name "*.lock" | xargs rm -- find $HOME/.ivy2 -name "ivydata-*.properties" | xargs rm -cache: - directories: - - "$HOME/.ivy2/cache" - - "$HOME/.sbt" -language: scala -scala: - - 2.12.10 - - 2.11.12 -jdk: -- oraclejdk8 -stages: -- test -- name: release - if: tag =~ ^v -- name: snapshot - if: "(NOT tag IS present) AND (type = push)" -jobs: - include: - - stage: test - script: sbt -jvm-opts .travis.jvmopts +coverage +test && sbt +coverageReport coverageAggregate coveralls - - stage: release - # decrypt the private key (exported via https://docs.scala-lang.org/overviews/contributors/index.html#export-your-pgp-key-pair ) - script: openssl aes-256-cbc -K $encrypted_98cf3af00429_key -iv $encrypted_98cf3af00429_iv -in ci/secring.asc.enc -out ci/secring.asc -d && gpg --import ci/secring.asc && sbt -jvm-opts .travis.jvmopts +publishSigned sonatypeBundleRelease - - stage: snapshot - script: sbt -jvm-opts .travis.jvmopts +publish -env: - global: - - secure: IGwd+lY2TfkAeX1SfzaYBwyhiiPaFrTxoF0e+4R1bkGxiGCce1hBYjn15z1HRfK+k3hgEZh/FBG7dv8LQfNWQ6AJY5PQ2zwckd4ArYMhTVpiY4eRzUMqO1/gjTCCbbTjfFKOMsR2pAw+TGeglqoX4eyziIaS8nR901dZcFvHuC1Fr5EdKFZ0x+WHnX8vaSQoDE4u1MoBnyo5cRVumXG+xvs1Q0nZXm/hd/Flfx5u3L7veKAkGtvbHmdsJoSSySTbc1MGYQtofQjbjd9AVvUhgfP32J63UCC2SqgWWKVvIjW+dUn414BV3lelnWR3FdzhC7AUJqYWVfSILh1aj3STnizRnjtCScmyoRz4ldUQ3jr4jBJOREUEus5YH2EqY1MGjX+8kUu9IjDYiQyNy1EdivcmMlXCOcAW2mi4rGDRxZOeFt1ZSHzxqSghZOFwvk/OFcdDzV4/3OnAcGz8LH5qjZU/edjmfkSls5CqxuAFqeD7RZWIu0ccjt6dzQZAf02lBX9kQuwIruC4x4E0iEjml7jmaEeOT4Hqk7wAo6EFMSEkj4EnS/Kln6Wr7JBut5qrMk0+PDgvxaKCaN8LeycCSQdoXfPO602WzfasNcOJexSmGMAE5NYfeXjq1h3F9AVHJ3TbNAOdlQTHbSOqt7WO10JphljYnFEu4aSzvaA3E60= - - secure: g4Egz1orKgCAgTckMYHHbpsFY8ppldLLUkBi0GasHN4M2zhfYlqzaJ+ZZ4soMPNshcS3XutGS+/ERF5zrnHF1C9h3txW6AJkgMkTF1q4UyKan25chdPnz1nNUrdQOvaCA4CzLIN3aQAHN40p44ELxfNTARTfbUAIcqNSrKmXZsUbhQg9yyM+gFL6cCw7SYQphC9GJq4mvW19dzzpU8MQ0AtktB6mscuUyiWgniHsnFAmeQBv0csCiMyjUsT1buIkO0gSvZBKkLXu7kXhash/mLjrBYGapVGGFORA3pWy9JCB9OfxV8Bj1wNUqPyAImjGgVfgK6RxOnQ/C4GTsf8uVH/sYIiPnzPmbCrO7fQee68/+SWtZc1kko8HuiqHvouNHmKQy+Hwku2AIdp6nZDhOuFtQTP1PbkYLrdNj1evAI6913rq51e7vDWTriWmOKjMz2m4Tj2HGJx0VS0pNOZkpxwVhHOdyc1UXurpBKgkYis1HVcaEM3trFzhsMf7kllNvJLA1COwg7KbVebKwA9gXfYrKAp6p76YMaSYodSDq9VaSDPF/2MVCZYXs+FAUZ3MzcsAZ7TegSX2OWrrneGArjcQgdMLUetm+UgBFZF7pG3BpjMLVwMgp9ulUNkq1sP1vLU08cvQv6A3W/kcyrVyCNzg80XTQqDpxz7hCTbyBSw= - - secure: gfhEv/PXEckwZPnwJHl4fBCJKCrCKK4KMeYCPNZZtKuV1gC4mZscvECm8r+kgB+o2G3i4tEIYcIC5Jbdcbjf4bk6uNZW/X3dna0irl/Mdswt7rTLzLan1rPz3k8Bylgs8ehETFBGr8HyNitEa8ODyaEXa84MPQaucXUmpHS+sUEhQn0Z70T70d1H9ZubUhGv9VLltNoSWkPGW5CPZlpQTHl63ZShfmylfQuQVTbVMdL8LLUHn2x2edlDKMGD8YPH5d+of0AKc3IKnlnMM36WjgYVsf1yehfLi0NH/b2Dzk7wLjetu/bw8Cu9Ne6/u0Lu83Hbh4DyS2iPQivDUGB+JXlHDFI4uji3GurnvpFDku1gbc4HVoFqhgOWyXQAiRllj2BXmq2vwp6797TUG4HrD2EVzIJV7eIZdWNN/QttZtNxNdSbBq8QQc92G2SU4q7PcogMSr0LpX05SfyL1sMgX2WeGzFzyMIu/+rAJhG0lPt7krBxEfQrRtTLdJ9eyeFjFQlxM6G/9gk68j+Nida6KunLwe9QEl2T+t1YbE4i9pndoCMJFxAOjirhw5OM3PfSWfb/mU7zXd4PSNK7RQIdOaPJff5C6UEM7h/iQ6riRZp1Pn7d/rxppTXsvUbtvwUYnkoOeUZyMvQNQsPI6Slns8jWl0zp5XiTmzSRVOuH3ME= diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..ff928680e4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,4 @@ +## Releasing +To publish release version to Sonatype, do the following: +- make a tag with version number `vX.Y.Z` (used by `sbt-dynver` to set `version` in `build.sbt`); +- use the new tag to make a Github release, which triggers [`release.yml`](.github/workflows/release.yml) workflow and publishes release version to Sonatype; diff --git a/build.sbt b/build.sbt index 0cad69bd90..e6adf65cdf 100644 --- a/build.sbt +++ b/build.sbt @@ -43,39 +43,19 @@ lazy val commonSettings = Seq( , publishMavenStyle := true, - publishTo := sonatypePublishToBundle.value + publishTo := sonatypePublishToBundle.value, + scmInfo := Some( + ScmInfo( + url("https://github.com/ScorexFoundation/sigmastate-interpreter"), + "scm:git@github.com:ScorexFoundation/sigmastate-interpreter.git" + ) + ), ) -enablePlugins(GitVersioning) - -version in ThisBuild := { - if (git.gitCurrentTags.value.nonEmpty) { - git.gitDescribedVersion.value.get - } else { - if (git.gitHeadCommit.value.contains(git.gitCurrentBranch.value)) { - // see https://docs.travis-ci.com/user/environment-variables/#default-environment-variables - if (Try(sys.env("TRAVIS")).getOrElse("false") == "true") { - // pull request number, "false" if not a pull request - if (Try(sys.env("TRAVIS_PULL_REQUEST")).getOrElse("false") != "false") { - // build is triggered by a pull request - val prBranchName = Try(sys.env("TRAVIS_PULL_REQUEST_BRANCH")).get - val prHeadCommitSha = Try(sys.env("TRAVIS_PULL_REQUEST_SHA")).get - prBranchName + "-" + prHeadCommitSha.take(8) + "-SNAPSHOT" - } else { - // build is triggered by a push - val branchName = Try(sys.env("TRAVIS_BRANCH")).get - branchName + "-" + git.gitHeadCommit.value.get.take(8) + "-SNAPSHOT" - } - } else { - git.gitHeadCommit.value.get.take(8) + "-SNAPSHOT" - } - } else { - git.gitCurrentBranch.value + "-" + git.gitHeadCommit.value.get.take(8) + "-SNAPSHOT" - } - } -} - -git.gitUncommittedChanges in ThisBuild := true +// prefix version with "-SNAPSHOT" for builds without a git tag +dynverSonatypeSnapshots in ThisBuild := true +// use "-" instead of default "+" +dynverSeparator in ThisBuild := "-" val bouncycastleBcprov = "org.bouncycastle" % "bcprov-jdk15on" % "1.64" val scrypto = "org.scorexfoundation" %% "scrypto" % "2.1.10" diff --git a/.travis.jvmopts b/ci/ci.jvmopts similarity index 100% rename from .travis.jvmopts rename to ci/ci.jvmopts diff --git a/ci/import_gpg.sh b/ci/import_gpg.sh new file mode 100755 index 0000000000..b1eb66e0bd --- /dev/null +++ b/ci/import_gpg.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# setting up gpg2 for reading passphrase from parameters +# via https://github.com/beautiful-scala/scalastyle/blob/master/.github/workflows/release.yml#L16 +# from https://github.com/olafurpg/sbt-ci-release/issues/95 + +# setup gpg +mkdir ~/.gnupg && chmod 700 ~/.gnupg +echo use-agent >> ~/.gnupg/gpg.conf +echo pinentry-mode loopback >> ~/.gnupg/gpg.conf +echo allow-loopback-pinentry >> ~/.gnupg/gpg-agent.conf +chmod 600 ~/.gnupg/* +echo RELOADAGENT | gpg-connect-agent + +# decode key +# private key should be previously exported with: +# gpg --export-secret-keys [id] | base64 | pbcopy +# and stored as github repository secret under the following name (see env var name below) +printf "$GPG_SIGNING_KEY" | base64 --decode > ~/.gnupg/private.key + +# import key +gpg --no-tty --batch --yes --import ~/.gnupg/private.key diff --git a/ci/pubring.asc b/ci/pubring.asc deleted file mode 100644 index cf75b9dfab..0000000000 --- a/ci/pubring.asc +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -mQENBF2utdgBCAClRGOfWeus4AlHvCBgJVXH2CLqXLKCBggE2vwKbKvFdW1DTPZQ -T1RI6zBtMdaSNVm4ISO4dOO67VGdajr8/6kFt2+di2b7hMVaULf4UgYuZ+vvVUPp -3oSEJnHheh5ZfjV+jvL5GSAu+vgnC8qbPutCEpXBfx5zAOdLtiyegzx72asJvvkz -ghvyXVrg8gnXVtiSBV1EpfES7gZJmpuzv2dYrCtL2irlRlySLQ5JFKXrfOQvf4K9 -TCxRye1UNb+3ybL0ilXoRn3jDS9RLbLxiVMjjx/Bqk/mc3MNMoa+juzvI6xIxFG0 -3fwNOTXdQ6gLCjHJ9/nFvygkBW5bkeMujBhhABEBAAG0JlNpZ21hc3RhdGUgYm90 -IDxkZW55c0B6YWRvcm96aG55aS5jb20+iQFUBBMBCAA+FiEEKOJ6Z66jjaRYxyIo -ypJUteBkD+QFAl2utdgCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AA -CgkQypJUteBkD+Tt4Af/f5o2Yoc8ebOwMiNUYDkfUqFLzH1WySEKfAt2iXrIgVjV -NF6ddyaLadSYdU6HGJ6txn2a16TuItdBQJSTpnmiw1qtqNVJVRnUoytXeCYN0Utn -+3zYTOhkbhnIczGao+qlqhovfO8x+WPZ/2Fczm20A5TNAg7NzmeF7FP9OWLpnI4v -yktmAbpZaSoCZWC3ZPG2H3SOHUn8Lt0++ni4R0gT0HclwbyzuDgT0cmxarVzEFQQ -7nhNOhU1+1MYRpQ9wBUWFLwMvMUgA6rQeg7idtAXklGEZaN0RK3HpL1I+XAE9rYW -tdejY67u/hdInm33oqe5aJrPmH5DFNCpBpc2w2NzGbkBDQRdrrXYAQgAxGs1Fclq -MQJjIwu3dH+vBY5vdZ0M1Mhd2fjXu8s0tEZ8RjBBbtZ03KI5t97+oXs5rgKCCtRH -v+RfSDn1eTeKRIwYxsowd86SlC8rjhSAyJfWS7er7+4Jpsa1W91TucrMQMue4qEX -udlg18oNcX/MGDB+lPirL1zxp6jfysjlebx01dcKVj2a+rpyPeNNrV2M8Ywlm5/c -lmRciSXLMb+phhvcyYyvi4UmguQi7/o3hCNhRlEj4XqF6CT1S57X6nTuYRP1dcjG -GVxvlybrDIBV0oDGW0TEjGWaBwKOpqZDi8Jzj5P398nqnP0UDrW7q/qmrZcdE5ov -qYWERLqXzGwBFwARAQABiQE8BBgBCAAmFiEEKOJ6Z66jjaRYxyIoypJUteBkD+QF -Al2utdgCGwwFCQPCZwAACgkQypJUteBkD+Qbqwf+IR030kbKsE6rOLwlKUGN9pah -tZjoSxnq5K+nXn621K578z9r76rGkP84UeAvZqt2MkadhwyEqwv99DftoZCXNM8b -5oRsDOAbA0YTSPKIa8E7S8XhWzE6VCx+2DFtjrYeGhybVGd9aq6jeQgEkqioZT0n -l3acH1VsuFQdFNwBrEgAFORBt5zXtSn7lXmnOh4ZFeYCncdR3+L6nJ/PAPz0hWMz -CZjc7vGcEvAtTNb2brtHtvox0Gc0Xphe0iCaWyzN7P32+rJgsfCMj9FFQUxToZMY -ozM9at2zWzk9wOb41RLnY+rGBNQ3xNR23shWF4fcOwk6BIp+OYsSqnsEYYXuDw== -=huRW ------END PGP PUBLIC KEY BLOCK----- diff --git a/ci/secring.asc.enc b/ci/secring.asc.enc deleted file mode 100644 index 2cc0474c8955a6350b0417df05601b34b71e02c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3664 zcmV-W4zKZ;6S@eTH09UAL=`D;lHFoo%d8&I_o;;0{t}?f+1-WlyCEGF6d~`XSxcw2 zffPVzb`5b#J)=FT))>zzeuSxO_}k+yNTNh51nlj_5xK)(T)bXhGi ze_WvzEM?6ZM1dUlH>k8`>;PofiGi%dLP1J=X*FDl3RL^RUav)X>HB2=wzh=9JHVe4 zQRzK}_0muA;HMsaeTbpuu0hlfw;_Hf*Z_L;{AUXqAxLDHLccdj$P6cYB2~*9 z9dV2^%uO^xhaiZ|`$x079(d=Doks;_NbQUo)>#gGz%D<6jit8RMCXBwoBV_+8fPU| z*-RRfD22uAxy8V?Hv&QJ-bDnlNgKM)lrX2QMcMAqmVvJcwp;CEyjo714bGVT@#1Vb z!^gXhyKmdG7#TZHNBXJI)wng9OfcoJ--^m_#&(hd2j$n;t3$-?vm6B4xkor#tIc*9 zD-8HHS^0Z+F)}xys~#V~H|&JroqubP__uHW6lVR_$S*% zS$@FHSU8c1IdL=oD_NtLWYy{3ZN{30?xvUNq`|E@c&I2hZf2c@qRjQ0V_?_+e=Dws z{P1wzfSFiP2$&4qDhI27NWDaxMu@9eqwj!0m z-&TkrT4I+{RlSY7?cXDrcS*N?K32$XZdIERZH+GmkF3g9yBSz4E?VSKy>@`H-=IZe z&(U9qkXQmIP+Upv@^bMUW7_o;?nh=r&OK_K?!$N=flw`s=Y`t#ciX{8dkBB%R&BI{ z#{wC+<_)@c%rFWj+{jqrOMU8-pi*9(cJ*L&+Dnv>{S&7Y>A#B9`P3vE<3{29N;Pn2 zmbMdIO1did?1@{d+adpU{4IaO(8dqo{7?Sbf$1cT@0eHHGh_Bunc*#26u{;V)eMJ* zCN_xB@uds+4X1+AgY&iv8~Lp4!CRH&`3BhpqeCuZdnRf91A6PUC& zDziG%sdVZ+xx1Jt+p83*QvUKqr~Ga%SdU)2F-uj$f=0Mmh7JJv4KYZ_$qJB5ml6w?i`3^ zUT^zPh%o`XXqcYZ-4GiSHM>-s8$y|Hm$Q^dZ;~ym*dnGaoo+4lZ9=X7jfEu8{d2`F>Fpe#I=23@!qPDDmI14dg}Aq9+s&`5~>RPj?Aihu54K&3s~lLWSg z;-ZF{H$gLu7qBnTQpLGLU8Jn1$OoiA*L{iyLc`>~K+o4~!Y~B`b*J11SZL6kge3}q>Mb{Nxzvzum}RRw45g#cn$~{! zbrg=rpF=};0}$GXPF>8w=!OngIp;_-H@geS2IMq_6>2$>sE-StzW^8LPW-Zp1g{3P zQ@p`cJ7;%!(}oOiBX7g7B##!+^66Rm+uXB>M2EO=w=!|?n{M{v_5MT@39N2sMx7~J zRH#J}^e-q=NQT*n3fOu~ck?PTB>S;vm+Kr$^ca>MK*c-RLM+M0QcL$y0|~s`U4g8h z6?KdPS1cSRE(*b%4IPRzRf`(3@-?HJoc5veQF!kg4+9a|$qTx2cY)9zgTv1fdIw?w zx+H{}3EW4q?LXQ-)(-{f1m1utIKbHvwEm`&IkrQ2l==D!e>6shexhM%z@iqHt`8K2p44oqjU#nwDsP4JkWn_aQ zCRc4n;|dd$W$Ux~yB=4Qq^k|yQ+MT5WFQ!*yC7Cl`=t-4qN&CK2%Lz219d;R*@@Ae z8}zz4hOyHD+%O*I3F1C01q%b`4G(6l8D&CLzK8e$F}hhy3_yHe83 z!u2GOg88UP8dT0Tk@zg+o7M%yNTnct-;B{vtL~2?k1Vv+9Ptu#cLi}kfDzDsB*m-u zx!0R{?vU1T*7OVp;#%n~Mdal-o9tku|HB~-37Q4xqSv_PM$?!}QJ$IyHbO4j4<%#A ziVIq-AI9=S!`&Zr+p1AhtbCWHQ;RB(vBIZW+#Y3AC?>%bC&zQQ)g6_mIFyVyC!CE})^Wcs~4zF6R&#%OqKXL6;7ON^j&2jKRVc2v3BruDHcZA6R6DkaE~3se+^C9%@2BkCIDWc+edj% zRMk~Ex&?wDj8D)EC)_ZUaM3~;tc<&uc_Lhqh@+xk>?W$7Jvca*+&K&ys)L>+jdV-6 zZOp(VK(#2oHh6F~^r6W688o!8zI^%ndOeX1gZkK!zOJ>?hufnzYqCfHr9q&oL~-Hi zd?~DzYdSR~b@@|o(>RvJs0_<`0L*QF&hw#lo#F6MtGlo1JJfq_vVY>6}2hmg4H0?^1;#y)9gY# zc;09@HLp9X%5nE#R0#!TKr~u~Yq9K1eZEDsfdvgsHAB2bC>AEuq;ynm|7jB*Pcw5( zIeaZjDe3%^%i#l`gaOB33^rFk;YV_S9PGAI<|px+$)^i*=c&+Zk3!&6ayZ+VBgw)t zSf+j9Q!wmplL8k|HMZFZgB@QH%I*ceacyO%fJTfUNbRyB6ZD8U@VG8Aak&4`!2&JO z^RFOO?`=dPK2WifZ|C+$dlz;?6=ae5;X&yJNE-0q_9r1BHw((}gl&>^=b!~3=A^(A zurg;9VQa!~X@~u{kT7e|9aYj%zXyD&V-Txyv?I{1S!Fqk74m4u&-FyM!zM<<5i%tQn)itHv%g3f}SFtRLL+&CS z;%}Ncq_4V&9W`JF)w$rG9q}Wv9p?ZcYpvlfSVo8fD!!#vjLPC#mu5mv#lr_bp&@FE zqk%jv5v)c3sqX{}fYnZjz6W1#gu&`M3%7yrVW}X+5(PyKb5Vw}JICP3 z!af)lGbiWrgxeEd)XUlshI5}cFf--sj3sL!_zXBmhXy}{^n z$$?{?f^{gR?none>r<_fK{zVvaWT0Vw7g#Xd|a+Qu&BeCQgHG2DOS^J4b)lN{aW8v_A-&At(n) ikYk4BwR7Q4kRLS8JsGZ6uTW%%ZGsq&;!ie;3X01Ry%$#i diff --git a/project/build.properties b/project/build.properties index 72f902892a..c06db1bb2e 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.7 +sbt.version=1.4.5 diff --git a/project/plugins.sbt b/project/plugins.sbt index 7964090b4d..b9cfa44119 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,9 +2,9 @@ logLevel := Level.Warn addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0") -addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0") addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.2") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1") addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.2.7") -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.8") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0") \ No newline at end of file +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.5") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0") +addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") \ No newline at end of file From 67cd44014186b8bf1c19513c67869d9cdeaafe12 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 24 Dec 2020 12:02:18 +0300 Subject: [PATCH 30/31] v4.0: fix compilation --- .../scala/org/ergoplatform/ErgoLikeContext.scala | 14 ++++++++++---- .../sigmastate/interpreter/ProverInterpreter.scala | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index e94aa30937..8467a24ee7 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -8,7 +8,7 @@ import sigmastate.Values._ import sigmastate._ import sigmastate.eval.Extensions._ import sigmastate.eval._ -import sigmastate.interpreter.{ContextExtension, InterpreterContext, Interpreter} +import sigmastate.interpreter.{ContextExtension, InterpreterContext} import sigmastate.serialization.OpCodes import sigmastate.serialization.OpCodes.OpCode import special.collection.Coll @@ -42,6 +42,11 @@ import spire.syntax.all.cfor * This means Ergo node should always pass Interpreter.MaxSupportedScriptVersion * as a value of ErgoLikeContext.activatedScriptVersion during * verification of candidate blocks (which is a default). + * The following values are used for current and upcoming forks: + * - version 3.x this value must be 0 + * - in v4.0 must be 1 + * - in v5.x must be 2 + * etc. */ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, val headers: Coll[Header], @@ -108,8 +113,8 @@ class ErgoLikeContext(val lastBlockUtxoRoot: AvlTreeData, override def withCostLimit(newCostLimit: Long): ErgoLikeContext = ErgoLikeContext.copy(this)(costLimit = newCostLimit) - override def withInitCost(newCost: Long): ErgoLikeContext = - ErgoLikeContext.copy(this)(initCost = newCost) + override def withInitCost(newInitCost: Long): ErgoLikeContext = + ErgoLikeContext.copy(this)(initCost = newInitCost) override def withValidationSettings(newVs: SigmaValidationSettings): ErgoLikeContext = ErgoLikeContext.copy(this)(validationSettings = newVs) @@ -214,7 +219,8 @@ object ErgoLikeContext { activatedScriptVersion: Byte = ctx.activatedScriptVersion): ErgoLikeContext = { new ErgoLikeContext( lastBlockUtxoRoot, headers, preHeader, dataBoxes, boxesToSpend, - spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost, activatedScriptVersion) + spendingTransaction, selfIndex, extension, validationSettings, costLimit, initCost, + activatedScriptVersion) } } diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index a64adb3bae..1c7cc0082c 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -12,6 +12,7 @@ import sigmastate._ import sigmastate.basics.DLogProtocol._ import sigmastate.basics.VerifierMessage.Challenge import sigmastate.basics._ +import sigmastate.lang.exceptions.CostLimitException import sigmastate.utils.Helpers import scala.util.Try From dfce8f899ac966a84ddf7871bd908b21d126dbe6 Mon Sep 17 00:00:00 2001 From: Alex Chepurnoy Date: Mon, 4 Jan 2021 23:09:09 +0300 Subject: [PATCH 31/31] unused import, typo fix --- sigmastate/src/main/scala/sigmastate/Values.scala | 1 - .../src/main/scala/sigmastate/interpreter/Interpreter.scala | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index 3264b1772f..17d0b860c8 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -37,7 +37,6 @@ import sigmastate.lang.SourceContext import special.collection.Coll import scala.collection.mutable -import scala.collection.mutable.ArrayBuffer object Values { diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index 3d13f00642..5aee794a74 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -233,7 +233,7 @@ trait Interpreter extends ScorexLogging { val (res, t) = BenchmarkUtil.measureTime(Try { // TODO v5.0: the condition below should be revised if necessary // The following conditions define behavior which depend on the version of ergoTree - // This works in addition to more fine-grained soft-forkabiltiy mechanism implemented + // This works in addition to more fine-grained soft-forkability mechanism implemented // using ValidationRules (see trySoftForkable method call here and in reduceToCrypto). if (context.activatedScriptVersion > Interpreter.MaxSupportedScriptVersion) { // > 90% has already switched to higher version, accept without verification