From ac112372c0956d879bc587cf3cafa0b80eae1bd8 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 15 Oct 2024 13:12:46 +0300 Subject: [PATCH 01/25] CheckAndGetMethod/CheckAndGetMethodV6, versioned methodById --- .../org/ergoplatform/validation/ValidationRules.scala | 9 +++++++-- data/shared/src/main/scala/sigma/ast/methods.scala | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index 9d4de47a99..9cf5828803 100644 --- a/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -102,7 +102,7 @@ object ValidationRules { // } } - object CheckAndGetMethod extends ValidationRule(1011, + class CheckAndGetMethodTemplate(ruleId: Short) extends ValidationRule(ruleId, "Check the type has the declared method.") { override protected lazy val settings: SigmaValidationSettings = currentSettings @@ -128,6 +128,9 @@ object ValidationRules { } } + object CheckAndGetMethod extends CheckAndGetMethodTemplate(1011) + object CheckAndGetMethodV6 extends CheckAndGetMethodTemplate(1016) + object CheckHeaderSizeBit extends ValidationRule(1012, "For version greater then 0, size bit should be set.") with SoftForkWhenReplaced { override protected lazy val settings: SigmaValidationSettings = currentSettings @@ -171,7 +174,9 @@ object ValidationRules { CheckHeaderSizeBit, CheckCostFuncOperation, CheckPositionLimit, - CheckLoopLevelInCostFunction + CheckLoopLevelInCostFunction, + // v6 validation rules below + CheckAndGetMethodV6 ) /** Validation settings that correspond to the current version of the ErgoScript implementation. diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index dc85205b37..7fbe2017aa 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -83,7 +83,11 @@ sealed trait MethodsContainer { * @see getMethodById */ def methodById(methodId: Byte): SMethod = { - ValidationRules.CheckAndGetMethod(this, methodId) + if (VersionContext.current.isV6SoftForkActivated) { + ValidationRules.CheckAndGetMethodV6(this, methodId) + } else { + ValidationRules.CheckAndGetMethod(this, methodId) + } } /** Finds a method descriptor [[SMethod]] for the given name. */ From 901c868b69e4ec23ca1a8a50f538b0b90f6233cd Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 29 Oct 2024 19:18:05 +0300 Subject: [PATCH 02/25] 1007 & 1008 replacement & versioning --- .../scala/sigma/serialization/TypeSerializer.scala | 14 ++++++++++---- .../scala/sigma/validation/ValidationRules.scala | 12 ++++++++++-- data/shared/src/main/scala/sigma/ast/methods.scala | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala b/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala index 1936bbcd9a..fcd8885664 100644 --- a/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala +++ b/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala @@ -5,7 +5,7 @@ import sigma.VersionContext import sigma.ast.SCollectionType.{CollectionTypeCode, NestedCollectionTypeCode} import sigma.ast._ import sigma.util.safeNewArray -import sigma.validation.ValidationRules.{CheckPrimitiveTypeCode, CheckTypeCode} +import sigma.validation.ValidationRules.{CheckPrimitiveTypeCode, CheckTypeCode, CheckTypeCodeV6} import java.nio.charset.StandardCharsets @@ -14,6 +14,8 @@ class TypeSerializer { import TypeSerializer._ def getEmbeddableType(code: Int): SType = { + // todo : add versioning to the check like done for other rules + // todo : add unsigned bit int to embeddable id to type CheckPrimitiveTypeCode(code.toByte) embeddableIdToType(code) } @@ -215,9 +217,13 @@ class TypeSerializer { } SFunc(tDom, tRange, tpeParams) case _ => - // todo: 6.0: replace 1008 check with identical behavior but other opcode, to activate - // ReplacedRule(1008 -> new opcode) during 6.0 activation - CheckTypeCode(c.toByte) + // the #1008 check replaced with one with identical behavior but different opcode (1018), to activate + // ReplacedRule(1008 -> 1018) during 6.0 activation + if (VersionContext.current.isV6SoftForkActivated) { + CheckTypeCodeV6(c.toByte) + } else { + CheckTypeCode(c.toByte) + } NoType } } diff --git a/core/shared/src/main/scala/sigma/validation/ValidationRules.scala b/core/shared/src/main/scala/sigma/validation/ValidationRules.scala index 249e2fce0a..7cc552b140 100644 --- a/core/shared/src/main/scala/sigma/validation/ValidationRules.scala +++ b/core/shared/src/main/scala/sigma/validation/ValidationRules.scala @@ -77,7 +77,7 @@ object ValidationRules { /** The id of the first validation rule. Can be used as the beginning of the rules id range. */ val FirstRuleId = 1000.toShort - object CheckPrimitiveTypeCode extends ValidationRule(1007, + class CheckPrimitiveTypeCodeTemplate(ruleId: Short) extends ValidationRule(ruleId, "Check the primitive type code is supported or is added via soft-fork") with SoftForkWhenCodeAdded { override protected lazy val settings: SigmaValidationSettings = coreSettings @@ -93,7 +93,11 @@ object ValidationRules { } } - object CheckTypeCode extends ValidationRule(1008, + object CheckPrimitiveTypeCode extends CheckPrimitiveTypeCodeTemplate(1007) + + object CheckPrimitiveTypeCodeV6 extends CheckPrimitiveTypeCodeTemplate(1017) + + class CheckTypeCodeTemplate(ruleId: Short) extends ValidationRule(ruleId, "Check the non-primitive type code is supported or is added via soft-fork") with SoftForkWhenCodeAdded { override protected lazy val settings: SigmaValidationSettings = coreSettings @@ -109,6 +113,10 @@ object ValidationRules { } } + object CheckTypeCode extends CheckTypeCodeTemplate(1008) + + object CheckTypeCodeV6 extends CheckTypeCodeTemplate(1018) + object CheckSerializableTypeCode extends ValidationRule(1009, "Check the data values of the type (given by type code) can be serialized") with SoftForkWhenReplaced { diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index 052d0bac48..f3fa1785fb 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -77,7 +77,7 @@ sealed trait MethodsContainer { /** Lookup method in this type by method's id or throw ValidationException. * This method can be used in trySoftForkable section to either obtain valid method - * or catch ValidatioinException which can be checked for soft-fork condition. + * or catch ValidationException which can be checked for soft-fork condition. * It delegate to getMethodById to lookup method. * * @see getMethodById From b3a10a555e45fd30077918cefaac523d76290e00 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 14 Nov 2024 23:26:39 +0300 Subject: [PATCH 03/25] 1007 rule update --- .../main/scala/sigma/serialization/TypeSerializer.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala b/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala index fcd8885664..e56744efd6 100644 --- a/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala +++ b/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala @@ -5,7 +5,7 @@ import sigma.VersionContext import sigma.ast.SCollectionType.{CollectionTypeCode, NestedCollectionTypeCode} import sigma.ast._ import sigma.util.safeNewArray -import sigma.validation.ValidationRules.{CheckPrimitiveTypeCode, CheckTypeCode, CheckTypeCodeV6} +import sigma.validation.ValidationRules.{CheckPrimitiveTypeCode, CheckPrimitiveTypeCodeV6, CheckTypeCode, CheckTypeCodeV6} import java.nio.charset.StandardCharsets @@ -14,9 +14,12 @@ class TypeSerializer { import TypeSerializer._ def getEmbeddableType(code: Int): SType = { - // todo : add versioning to the check like done for other rules // todo : add unsigned bit int to embeddable id to type - CheckPrimitiveTypeCode(code.toByte) + if (VersionContext.current.isV6SoftForkActivated) { + CheckPrimitiveTypeCodeV6(code.toByte) + } else { + CheckPrimitiveTypeCode(code.toByte) + } embeddableIdToType(code) } From 491f87806b7c067d56493ed4f8a72d0e4ee798e0 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 15 Nov 2024 23:52:38 +0300 Subject: [PATCH 04/25] versioned rulesSpecs --- .../sigma/validation/ValidationRules.scala | 31 ++++++++++--- .../validation/ValidationRules.scala | 45 ++++++++++++------- .../scala/sigma/data/CSigmaDslBuilder.scala | 2 +- .../validation/ValidationSpecification.scala | 2 +- .../SoftForkabilitySpecification.scala | 2 +- 5 files changed, 55 insertions(+), 27 deletions(-) diff --git a/core/shared/src/main/scala/sigma/validation/ValidationRules.scala b/core/shared/src/main/scala/sigma/validation/ValidationRules.scala index 7cc552b140..6321ae6ba6 100644 --- a/core/shared/src/main/scala/sigma/validation/ValidationRules.scala +++ b/core/shared/src/main/scala/sigma/validation/ValidationRules.scala @@ -1,6 +1,6 @@ package sigma.validation -import sigma.SigmaException +import sigma.{SigmaException, VersionContext} import sigma.ast.{SGlobal, SOption, TypeCodes} import sigma.serialization.{ReaderPositionLimitExceeded, SerializerException} import sigma.util.Extensions.toUByte @@ -100,7 +100,7 @@ object ValidationRules { class CheckTypeCodeTemplate(ruleId: Short) extends ValidationRule(ruleId, "Check the non-primitive type code is supported or is added via soft-fork") with SoftForkWhenCodeAdded { - override protected lazy val settings: SigmaValidationSettings = coreSettings + override protected def settings: SigmaValidationSettings = coreSettings final def apply[T](typeCode: Byte): Unit = { checkRule() @@ -120,7 +120,7 @@ object ValidationRules { object CheckSerializableTypeCode extends ValidationRule(1009, "Check the data values of the type (given by type code) can be serialized") with SoftForkWhenReplaced { - override protected lazy val settings: SigmaValidationSettings = coreSettings + override protected def settings: SigmaValidationSettings = coreSettings /** Creates an exception which is used as a cause when throwing a ValidationException. */ def throwValidationException(typeCode: Byte): Nothing = { @@ -149,7 +149,7 @@ object ValidationRules { object CheckTypeWithMethods extends ValidationRule(1010, "Check the type (given by type code) supports methods") with SoftForkWhenCodeAdded { - override protected lazy val settings: SigmaValidationSettings = coreSettings + override protected def settings: SigmaValidationSettings = coreSettings final def apply[T](typeCode: Byte, cond: Boolean): Unit = { checkRule() @@ -168,7 +168,7 @@ object ValidationRules { */ object CheckPositionLimit extends ValidationRule(1014, "Check that the Reader has not exceeded the position limit.") with SoftForkWhenReplaced { - override protected lazy val settings: SigmaValidationSettings = coreSettings + override protected def settings: SigmaValidationSettings = coreSettings /** Wraps the given cause into [[ValidationException]] and throws it. */ def throwValidationException(cause: ReaderPositionLimitExceeded): Nothing = { @@ -191,7 +191,7 @@ object ValidationRules { } } - private val ruleSpecs: Seq[ValidationRule] = Seq( + private val ruleSpecsV5: Seq[ValidationRule] = Seq( CheckPrimitiveTypeCode, CheckTypeCode, CheckSerializableTypeCode, @@ -199,13 +199,30 @@ object ValidationRules { CheckPositionLimit ) + private val ruleSpecsV6: Seq[ValidationRule] = Seq( + CheckPrimitiveTypeCodeV6, + CheckTypeCodeV6, + CheckSerializableTypeCode, + CheckTypeWithMethods, + CheckPositionLimit + ) + + private def ruleSpecs: Seq[ValidationRule] = { + if(VersionContext.current.isV6SoftForkActivated) { + ruleSpecsV6 + } else { + ruleSpecsV5 + } + } + /** Validation settings that correspond to the current version of the ErgoScript implementation. * Different version of the code will have a different set of rules here. * This variable is globally available and can be use wherever checking of the rules is necessary. * This is immutable data structure, it can be augmented with RuleStates from block extension * sections of the blockchain, but that augmentation is only available in stateful context. */ - val coreSettings: SigmaValidationSettings = new MapSigmaValidationSettings({ + // todo: versioned cache here for efficiency + def coreSettings: SigmaValidationSettings = new MapSigmaValidationSettings({ val map = ruleSpecs.map(r => r.id -> (r, EnabledRule)).toMap assert(map.size == ruleSpecs.size, s"Duplicate ruleIds ${ruleSpecs.groupBy(_.id).filter(g => g._2.length > 1)}") map diff --git a/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index 9cf5828803..4c75de6623 100644 --- a/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -1,6 +1,6 @@ package org.ergoplatform.validation -import sigma.SigmaException +import sigma.{SigmaException, VersionContext} import sigma.ast.{DeserializeContext, ErgoTree, MethodsContainer, SMethod} import sigma.ast.TypeCodes.LastConstantCode import sigma.serialization.{InvalidOpCode, SerializerException} @@ -23,7 +23,7 @@ object ValidationRules { object CheckDeserializedScriptType extends ValidationRule(FirstRuleId, "Deserialized script should have expected type") { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings final def apply[T](d: DeserializeContext[_], script: SValue): Unit = { checkRule() @@ -38,7 +38,7 @@ object ValidationRules { object CheckDeserializedScriptIsSigmaProp extends ValidationRule(1001, "Deserialized script should have SigmaProp type") { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings /** @param root candidate node before it is added as a root of ErgoTree */ final def apply[T](root: SValue): Unit = { @@ -54,7 +54,7 @@ object ValidationRules { object CheckValidOpCode extends ValidationRule(1002, "Check the opcode is supported by registered serializer or is added via soft-fork") with SoftForkWhenCodeAdded { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings final def apply[T](ser: ValueSerializer[_], opCode: OpCode): Unit = { checkRule() @@ -69,18 +69,18 @@ object ValidationRules { /** Not used since v5.0.1. */ object CheckIsSupportedIndexExpression extends ValidationRule(1003, "Check the index expression for accessing collection element is supported.") { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings } /** Not used since v5.0.3 */ object CheckCostFunc extends ValidationRule(1004, "Cost function should contain only operations from specified list.") { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings } object CheckCalcFunc extends ValidationRule(1005, "If SigmaProp.isProven method calls exists in the given function,\n then it is the last operation") { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings } /** This rule is not use in v5.x, keep the commented code below as a precise @@ -88,7 +88,7 @@ object ValidationRules { */ object CheckTupleType extends ValidationRule(1006, "Supported tuple type.") with SoftForkWhenReplaced { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings // final def apply[Ctx <: IRContext, T](ctx: Ctx)(e: ctx.Elem[_]): Unit = { // checkRule() @@ -104,7 +104,7 @@ object ValidationRules { class CheckAndGetMethodTemplate(ruleId: Short) extends ValidationRule(ruleId, "Check the type has the declared method.") { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings final def apply[T](objType: MethodsContainer, methodId: Byte): SMethod = { checkRule() @@ -133,7 +133,7 @@ object ValidationRules { object CheckHeaderSizeBit extends ValidationRule(1012, "For version greater then 0, size bit should be set.") with SoftForkWhenReplaced { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings final def apply(header: HeaderType): Unit = { checkRule() @@ -149,16 +149,16 @@ object ValidationRules { /** Not used since v5.0.3 */ object CheckCostFuncOperation extends ValidationRule(1013, "Check the opcode is allowed in cost function") { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings } /** Not used since v5.0.1 */ object CheckLoopLevelInCostFunction extends ValidationRule(1015, "Check that loop level is not exceeded.") { - override protected lazy val settings: SigmaValidationSettings = currentSettings + override protected def settings: SigmaValidationSettings = currentSettings } - val ruleSpecs: Seq[ValidationRule] = Seq( + private val ruleSpecsV5: Seq[ValidationRule] = Seq( CheckDeserializedScriptType, CheckDeserializedScriptIsSigmaProp, CheckValidOpCode, @@ -174,18 +174,29 @@ object ValidationRules { CheckHeaderSizeBit, CheckCostFuncOperation, CheckPositionLimit, - CheckLoopLevelInCostFunction, - // v6 validation rules below - CheckAndGetMethodV6 + CheckLoopLevelInCostFunction ) + // v6 validation rules below + private val ruleSpecsV6: Seq[ValidationRule] = { + ruleSpecsV5.filter(_.id != CheckAndGetMethod.id) ++ Seq(CheckAndGetMethodV6) + } + + def ruleSpecs: Seq[ValidationRule] = { + if (VersionContext.current.isV6SoftForkActivated) { + ruleSpecsV6 + } else { + ruleSpecsV5 + } + } + /** Validation settings that correspond to the current version of the ErgoScript implementation. * Different version of the code will have a different set of rules here. * This variable is globally available and can be use wherever checking of the rules is necessary. * This is immutable data structure, it can be augmented with RuleStates from block extension * sections of the blockchain, but that augmentation is only available in stateful context. */ - val currentSettings: SigmaValidationSettings = new MapSigmaValidationSettings({ + def currentSettings: SigmaValidationSettings = new MapSigmaValidationSettings({ val map = ruleSpecs.map(r => r.id -> (r, EnabledRule)).toMap assert(map.size == ruleSpecs.size, s"Duplicate ruleIds ${ruleSpecs.groupBy(_.id).filter(g => g._2.length > 1)}") map diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index 2ae4f73703..8090ad82f9 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -23,7 +23,7 @@ import java.math.BigInteger * @see [[SigmaDslBuilder]] for detailed descriptions */ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => - implicit val validationSettings: SigmaValidationSettings = ValidationRules.currentSettings + def validationSettings: SigmaValidationSettings = ValidationRules.currentSettings override val Colls: CollBuilder = sigma.Colls diff --git a/interpreter/shared/src/test/scala/org/ergoplatform/validation/ValidationSpecification.scala b/interpreter/shared/src/test/scala/org/ergoplatform/validation/ValidationSpecification.scala index b223355c5b..47068a9102 100644 --- a/interpreter/shared/src/test/scala/org/ergoplatform/validation/ValidationSpecification.scala +++ b/interpreter/shared/src/test/scala/org/ergoplatform/validation/ValidationSpecification.scala @@ -3,5 +3,5 @@ package org.ergoplatform.validation import sigma.validation.SigmaValidationSettings trait ValidationSpecification { - implicit val vs: SigmaValidationSettings = ValidationRules.currentSettings + def vs: SigmaValidationSettings = ValidationRules.currentSettings } diff --git a/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index c8b9f06399..bce875fd14 100644 --- a/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -289,7 +289,7 @@ class SoftForkabilitySpecification extends SigmaTestingData trySoftForkable(false) { action true - } + }(vs) }, { case ve: ValidationException if ve.rule == rule => true case _ => false From f482814fcdd308b631ecc48dad04919908718f27 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 6 Dec 2024 13:45:42 +0300 Subject: [PATCH 05/25] 6.0 specific serialization removed --- .../main/scala/sigma/serialization/CoreDataSerializer.scala | 4 ++-- .../src/main/scala/sigma/serialization/DataSerializer.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala b/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala index 175e91fbcb..8f739fad58 100644 --- a/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala +++ b/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala @@ -34,7 +34,7 @@ class CoreDataSerializer { val data = v.asInstanceOf[BigInt].toBigInteger.toByteArray w.putUShort(data.length) w.putBytes(data) - case SUnsignedBigInt if VersionContext.current.isV6SoftForkActivated => + case SUnsignedBigInt => val data = BigIntegers.asUnsignedByteArray(v.asInstanceOf[CUnsignedBigInt].wrappedValue) w.putUShort(data.length) w.putBytes(data) @@ -73,7 +73,7 @@ class CoreDataSerializer { i += 1 } - case SOption(elemType) if VersionContext.current.isV6SoftForkActivated => + case SOption(elemType) => val o = v.asInstanceOf[Option[elemType.WrappedType]] w.putOption(o){case (w, v) => serialize(v, elemType, w) diff --git a/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala b/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala index 92a54f9aa4..958f373195 100644 --- a/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala @@ -16,7 +16,7 @@ object DataSerializer extends CoreDataSerializer { case SBox => val b = v.asInstanceOf[CBox] ErgoBox.sigmaSerializer.serialize(b.ebox, w.asInstanceOf[SigmaByteWriter]) - case SHeader if VersionContext.current.isV6SoftForkActivated => + case SHeader => val h = v.asInstanceOf[CHeader] ErgoHeader.sigmaSerializer.serialize(h.ergoHeader, w.asInstanceOf[SigmaByteWriter]) case _ => From c1dc254f3ea0cc7a285ea573535a5362f6fda066 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 6 Dec 2024 14:33:11 +0300 Subject: [PATCH 06/25] ergoTreeVersion removed from VersionContext --- .../src/main/scala/sigma/VersionContext.scala | 18 ++++++++---------- .../serialization/ErgoTreeSerializer.scala | 2 +- .../interpreter/CErgoTreeEvaluator.scala | 5 ++++- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 6ede0a1556..053b1b086e 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -10,13 +10,10 @@ import scala.util.DynamicVariable * thread. * * @param activatedVersion Currently activated script version == Block.headerVersion - 1 - * @param ergoTreeVersion version of the currently executed ErgoTree * * @see */ -case class VersionContext(activatedVersion: Byte, ergoTreeVersion: Byte) { - require(ergoTreeVersion <= activatedVersion, - s"In a valid VersionContext ergoTreeVersion must never exceed activatedVersion: $this") +case class VersionContext(activatedVersion: Byte) { /** @return true, if the activated script version of Ergo protocol on the network is * greater than v1. */ @@ -51,8 +48,7 @@ object VersionContext { val V6SoftForkVersion: Byte = 3 private val _defaultContext = VersionContext( - activatedVersion = 1 /* v4.x */, - ergoTreeVersion = 1 + activatedVersion = 1 ) /** Universally accessible version context which is used to version the code @@ -92,16 +88,18 @@ object VersionContext { * @return result of block execution */ def withVersions[T](activatedVersion: Byte, ergoTreeVersion: Byte)(block: => T): T = - _versionContext.withValue(VersionContext(activatedVersion, ergoTreeVersion))(block) + _versionContext.withValue(VersionContext(activatedVersion))(block) /** Checks the version context has the given versions*/ - def checkVersions(activatedVersion: Byte, ergoTreeVersion: Byte) = { + def checkVersion(activatedVersion: Byte): Unit = { val ctx = VersionContext.current - if (ctx.activatedVersion != activatedVersion || ctx.ergoTreeVersion != ergoTreeVersion) { - val expected = VersionContext(activatedVersion, ergoTreeVersion) + if (ctx.activatedVersion != activatedVersion) { + val expected = VersionContext(activatedVersion) throw new IllegalStateException( s"Global VersionContext.current = ${ctx} while expected $expected.") } } + def fromBlockVersion(blockVersion: Byte): VersionContext = VersionContext((blockVersion - 1).toByte) + } diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 5122ee940c..95e8242029 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -74,7 +74,7 @@ import sigma.validation.ValidationRules.CheckPositionLimit * End of proof. * */ -class ErgoTreeSerializer { +class ErgoTreeSerializer(protocolVersion: Byte = VersionContext.V6SoftForkVersion) { /** Serialize header and constants section only.*/ private def serializeHeader(ergoTree: ErgoTree, w: SigmaByteWriter): Unit = { diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/CErgoTreeEvaluator.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/CErgoTreeEvaluator.scala index 9916a6c565..f2f605454c 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/CErgoTreeEvaluator.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/CErgoTreeEvaluator.scala @@ -220,7 +220,10 @@ class CErgoTreeEvaluator( /** Evaluates the given expression in the given data environment. */ def eval(env: DataEnv, exp: SValue): Any = { - VersionContext.checkVersions(context.activatedScriptVersion, context.currentErgoTreeVersion) + VersionContext.checkVersion(context.activatedScriptVersion) + require(context.currentErgoTreeVersion <= context.activatedScriptVersion, + s"ergoTreeVersion must never exceed activatedVersion: $this") + CErgoTreeEvaluator.currentEvaluator.withValue(this) { exp.evalTo[Any](env)(this) } From 2effbbab70a8b8bc349afb827c8b7a5b08dfbb11 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 6 Dec 2024 19:44:04 +0300 Subject: [PATCH 07/25] removing checkType parameter which is always true --- .../sigma/serialization/ErgoTreeSerializer.scala | 16 +++------------- .../sigmastate/interpreter/Interpreter.scala | 2 +- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 95e8242029..357ad4eb5a 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -127,12 +127,8 @@ class ErgoTreeSerializer(protocolVersion: Byte = VersionContext.V6SoftForkVersio val r = SigmaSerializer.startReader(bytes) deserializeErgoTree(r, SigmaSerializer.MaxPropositionSize) } - + def deserializeErgoTree(r: SigmaByteReader, maxTreeSizeBytes: Int): ErgoTree = { - deserializeErgoTree(r, maxTreeSizeBytes, true) - } - - private[sigma] def deserializeErgoTree(r: SigmaByteReader, maxTreeSizeBytes: Int, checkType: Boolean): ErgoTree = { val startPos = r.position val previousPositionLimit = r.positionLimit r.positionLimit = r.position + maxTreeSizeBytes @@ -158,9 +154,7 @@ class ErgoTreeSerializer(protocolVersion: Byte = VersionContext.V6SoftForkVersio val isUsingBlockchainContext = r.wasUsingBlockchainContext // == true if there was a node using the blockchain context r.wasUsingBlockchainContext = wasUsingBlockchainContext_saved - if (checkType) { - CheckDeserializedScriptIsSigmaProp(root) - } + CheckDeserializedScriptIsSigmaProp(root) r.constantStore = previousConstantStore // now we know the end position of propositionBytes, read them all at once into array @@ -391,8 +385,4 @@ class ErgoTreeSerializer(protocolVersion: Byte = VersionContext.V6SoftForkVersio (resBytes, nConstants) } -} - -object ErgoTreeSerializer { - val DefaultSerializer = new ErgoTreeSerializer -} +} \ No newline at end of file diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala index 88d7be4324..92f749e136 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -248,7 +248,7 @@ trait Interpreter { val context1 = context.withInitCost(currCost).asInstanceOf[CTX] val (propTree, context2) = trySoftForkable[(SigmaPropValue, CTX)](whenSoftFork = (TrueSigmaProp, context1)) { // Before ErgoTree V3 the deserialization cost was not added to the total cost - applyDeserializeContextJITC(if (VersionContext.current.activatedVersion >= VersionContext.V6SoftForkVersion) { + applyDeserializeContextJITC(if (VersionContext.current.isV6SoftForkActivated) { context1 } else { context From 8993b3afab938da9be4f0fbbe1a02a9d8a0b9598 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 6 Dec 2024 20:00:51 +0300 Subject: [PATCH 08/25] ergo tree version removed from withVersions --- .../src/main/scala/sigma/VersionContext.scala | 3 +-- .../src/test/scala/sigma/CollsTests.scala | 4 ++-- .../scala/sigma/VersionTestingProperty.scala | 2 +- .../serialization/ErgoTreeSerializer.scala | 6 ++++- .../sigmastate/interpreter/Interpreter.scala | 8 +++---- .../interpreter/ProverInterpreter.scala | 2 +- .../DataSerializerSpecification.scala | 12 +++++----- .../MethodCallSerializerSpecification.scala | 24 +++++++++---------- .../SerializationSpecification.scala | 2 +- .../scala/sigmastate/CrossVersionProps.scala | 2 +- .../scala/sigmastate/eval/BasicOpsTests.scala | 4 ++-- .../scala/sigmastate/lang/LangTests.scala | 2 +- .../ErgoAddressSpecification.scala | 2 +- .../sigma/LanguageSpecificationBase.scala | 2 +- .../test/scala/sigma/SigmaDslTesting.scala | 18 +++++++------- .../sigmastate/ErgoTreeSpecification.scala | 18 +++++++------- .../sigmastate/eval/ErgoScriptTestkit.scala | 2 +- .../utxo/BasicOpsSpecification.scala | 4 ++-- .../sdk/AppkitProvingInterpreter.scala | 2 +- .../sdk/DataJsonEncoderSpecification.scala | 6 ++--- 20 files changed, 64 insertions(+), 61 deletions(-) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 053b1b086e..d7110edc93 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -83,11 +83,10 @@ object VersionContext { * necessary versions of Ergo protocol and ErgoTree. * * @param activatedVersion Currently activated script version == Block.headerVersion - 1 - * @param ergoTreeVersion ErgoTree version to be set on the current thread * @param block block of code to execute * @return result of block execution */ - def withVersions[T](activatedVersion: Byte, ergoTreeVersion: Byte)(block: => T): T = + def withScriptVersion[T](activatedVersion: Byte)(block: => T): T = _versionContext.withValue(VersionContext(activatedVersion))(block) /** Checks the version context has the given versions*/ diff --git a/core/shared/src/test/scala/sigma/CollsTests.scala b/core/shared/src/test/scala/sigma/CollsTests.scala index da427ba576..612a1ea0b0 100644 --- a/core/shared/src/test/scala/sigma/CollsTests.scala +++ b/core/shared/src/test/scala/sigma/CollsTests.scala @@ -63,7 +63,7 @@ class CollsTests extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers equalLengthMapped(pairs, squared(inc)) // due to problem with append } } - VersionContext.withVersions(VersionContext.JitActivationVersion, VersionContext.JitActivationVersion) { + VersionContext.withScriptVersion(VersionContext.JitActivationVersion) { // TODO v5.0: make it work // equalLengthMapped(pairs, squared(inc)) // problem fixed in v5.0 } @@ -75,7 +75,7 @@ class CollsTests extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers equalLengthMapped(pairs.append(pairs), squared(inc)) // due to problem with append } } - VersionContext.withVersions(VersionContext.JitActivationVersion, VersionContext.JitActivationVersion) { + VersionContext.withScriptVersion(VersionContext.JitActivationVersion) { // TODO v5.0: make it work // equalLengthMapped(pairs.append(pairs), squared(inc)) // problem fixed in v5.0 } diff --git a/core/shared/src/test/scala/sigma/VersionTestingProperty.scala b/core/shared/src/test/scala/sigma/VersionTestingProperty.scala index 2c25359a89..b4c6e60465 100644 --- a/core/shared/src/test/scala/sigma/VersionTestingProperty.scala +++ b/core/shared/src/test/scala/sigma/VersionTestingProperty.scala @@ -17,7 +17,7 @@ trait VersionTestingProperty extends AnyPropSpec with VersionTesting { (implicit pos: Position): Unit = { super.property(testName, testTags:_*) { forEachScriptAndErgoTreeVersion(activatedVersions, ergoTreeVersions) { - VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + VersionContext.withScriptVersion(activatedVersionInTests) { testFun_Run(testName, testFun) } } diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 357ad4eb5a..1d14fcdc6b 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -127,7 +127,7 @@ class ErgoTreeSerializer(protocolVersion: Byte = VersionContext.V6SoftForkVersio val r = SigmaSerializer.startReader(bytes) deserializeErgoTree(r, SigmaSerializer.MaxPropositionSize) } - + def deserializeErgoTree(r: SigmaByteReader, maxTreeSizeBytes: Int): ErgoTree = { val startPos = r.position val previousPositionLimit = r.positionLimit @@ -385,4 +385,8 @@ class ErgoTreeSerializer(protocolVersion: Byte = VersionContext.V6SoftForkVersio (resBytes, nConstants) } +} + +object ErgoTreeSerializer { + val DefaultSerializer = new ErgoTreeSerializer } \ No newline at end of file diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala index 92f749e136..a9474d0c6b 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -204,7 +204,7 @@ trait Interpreter { ctx: CTX, env: ScriptEnv): ReductionResult = { val context = ctx.withErgoTreeVersion(ergoTree.version).asInstanceOf[CTX] - VersionContext.withVersions(context.activatedScriptVersion, ergoTree.version) { + VersionContext.withScriptVersion(context.activatedScriptVersion) { val prop = propositionFromErgoTree(ergoTree, context) val res = prop match { @@ -217,7 +217,7 @@ trait Interpreter { ReductionResult(sb, resCost) case _ if !ergoTree.hasDeserialize => val ctx = context.asInstanceOf[ErgoLikeContext] - val res = VersionContext.withVersions(ctx.activatedScriptVersion, ergoTree.version) { + val res = VersionContext.withScriptVersion(ctx.activatedScriptVersion) { CErgoTreeEvaluator.evalToCrypto(ctx, ergoTree, evalSettings) } res @@ -242,7 +242,7 @@ trait Interpreter { context: CTX, env: ScriptEnv): ReductionResult = { implicit val vs: SigmaValidationSettings = context.validationSettings - val res = VersionContext.withVersions(context.activatedScriptVersion, ergoTree.version) { + val res = VersionContext.withScriptVersion(context.activatedScriptVersion) { val deserializeSubstitutionCost = java7.compat.Math.multiplyExact(ergoTree.bytes.length, CostPerTreeByte) val currCost = addCostChecked(context.initCost, deserializeSubstitutionCost, context.costLimit) val context1 = context.withInitCost(currCost).asInstanceOf[CTX] @@ -359,7 +359,7 @@ trait Interpreter { case Some(resWhenSoftFork) => return Success(resWhenSoftFork) case None => // proceed normally } - VersionContext.withVersions(context.activatedScriptVersion, ergoTree.version) { + VersionContext.withScriptVersion(context.activatedScriptVersion) { // NOTE, ergoTree.complexity is not acrued to the cost in v5.0 val reduced = fullReduction(ergoTree, context, env) reduced.value match { diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index ed2349eb0f..d06287a8d3 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -134,7 +134,7 @@ trait ProverInterpreter extends Interpreter with ProverUtils { case None => // proceed normally } - VersionContext.withVersions(context.activatedScriptVersion, ergoTree.version) { + VersionContext.withScriptVersion(context.activatedScriptVersion) { val (resValue, resCost) = { val reduced = fullReduction(ergoTree, context, env) val fullCost = addCryptoCost(reduced.value, reduced.cost, context.costLimit) diff --git a/interpreter/shared/src/test/scala/sigma/serialization/DataSerializerSpecification.scala b/interpreter/shared/src/test/scala/sigma/serialization/DataSerializerSpecification.scala index 9201214e4f..500cdf02fb 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/DataSerializerSpecification.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/DataSerializerSpecification.scala @@ -52,7 +52,7 @@ class DataSerializerSpecification extends SerializationSpecification { withVersion match { case Some(ver) => - VersionContext.withVersions(ver, 1) { + VersionContext.withScriptVersion(ver) { test() } case None => @@ -122,14 +122,14 @@ class DataSerializerSpecification extends SerializationSpecification { val tT = Evaluation.stypeToRType(tpe) an[Exception] should be thrownBy ( - VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { + VersionContext.withScriptVersion((VersionContext.V6SoftForkVersion - 1).toByte) { forAll { in: T#WrappedType => roundtrip[SType](Some(in).asWrappedType, SOption(tpe)) roundtrip[SOption[SCollection[T]]](Some(Colls.fromItems(in)(tT)), SOption(SCollectionType(tpe))) } }) - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { forAll { in: T#WrappedType => roundtrip[SType](Some(in).asWrappedType, SOption(tpe)) roundtrip[SOption[T]](None, SOption(tpe)) @@ -189,12 +189,12 @@ class DataSerializerSpecification extends SerializationSpecification { } property("nuanced versioned test for header roundtrip") { - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { forAll { x: Header => roundtrip[SHeader.type](x, SHeader) } } an[SerializerException] should be thrownBy ( - VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { + VersionContext.withScriptVersion((VersionContext.V6SoftForkVersion - 1).toByte) { val h = headerGen.sample.get roundtrip[SHeader.type](h, SHeader) }) @@ -219,7 +219,7 @@ class DataSerializerSpecification extends SerializationSpecification { Colls.emptyColl ) - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { roundtrip[SHeader.type](header, SHeader) } } diff --git a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala index 4bfe3c6a25..abbf539727 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala @@ -38,12 +38,12 @@ class MethodCallSerializerSpecification extends SerializationSpecification { roundTripTest(expr) } - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { code } a[SerializerException] should be thrownBy ( - VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { + VersionContext.withScriptVersion((VersionContext.V6SoftForkVersion - 1).toByte) { code } ) @@ -65,12 +65,12 @@ class MethodCallSerializerSpecification extends SerializationSpecification { roundTripTest(expr) } - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { code } an[ValidationException] should be thrownBy ( - VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { + VersionContext.withScriptVersion((VersionContext.V6SoftForkVersion - 1).toByte) { code } ) @@ -87,12 +87,12 @@ class MethodCallSerializerSpecification extends SerializationSpecification { roundTripTest(expr) } - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { code } an[ValidationException] should be thrownBy ( - VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { + VersionContext.withScriptVersion((VersionContext.V6SoftForkVersion - 1).toByte) { code } ) @@ -111,12 +111,12 @@ class MethodCallSerializerSpecification extends SerializationSpecification { println(SGlobalMethods.deserializeToMethod.hasExplicitTypeArgs) - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { code } an[Exception] should be thrownBy ( - VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { + VersionContext.withScriptVersion((VersionContext.V6SoftForkVersion - 1).toByte) { code }) } @@ -133,12 +133,12 @@ class MethodCallSerializerSpecification extends SerializationSpecification { } // should be ok - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { code } an[ValidationException] should be thrownBy ( - VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { + VersionContext.withScriptVersion((VersionContext.V6SoftForkVersion - 1).toByte) { code }) } @@ -154,12 +154,12 @@ class MethodCallSerializerSpecification extends SerializationSpecification { roundTripTest(expr) } - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { code } an[ValidationException] should be thrownBy ( - VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { + VersionContext.withScriptVersion((VersionContext.V6SoftForkVersion - 1).toByte) { code } ) diff --git a/interpreter/shared/src/test/scala/sigma/serialization/SerializationSpecification.scala b/interpreter/shared/src/test/scala/sigma/serialization/SerializationSpecification.scala index aa7a8722ba..ae23712170 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/SerializationSpecification.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/SerializationSpecification.scala @@ -35,7 +35,7 @@ trait SerializationSpecification extends AnyPropSpec } withVersion match { case Some(ver) => - VersionContext.withVersions(ver, 0) { + VersionContext.withScriptVersion(ver) { test() } case None => diff --git a/interpreter/shared/src/test/scala/sigmastate/CrossVersionProps.scala b/interpreter/shared/src/test/scala/sigmastate/CrossVersionProps.scala index 87101a1f71..84600b0620 100644 --- a/interpreter/shared/src/test/scala/sigmastate/CrossVersionProps.scala +++ b/interpreter/shared/src/test/scala/sigmastate/CrossVersionProps.scala @@ -31,7 +31,7 @@ trait CrossVersionProps extends AnyPropSpecLike with TestsBase { System.gc() } forEachScriptAndErgoTreeVersion(activatedVersions, ergoTreeVersions) { - VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + VersionContext.withScriptVersion(activatedVersionInTests) { testFun_Run(testName, testFun) } } diff --git a/interpreter/shared/src/test/scala/sigmastate/eval/BasicOpsTests.scala b/interpreter/shared/src/test/scala/sigmastate/eval/BasicOpsTests.scala index 52cc6af66c..5ebf82d953 100644 --- a/interpreter/shared/src/test/scala/sigmastate/eval/BasicOpsTests.scala +++ b/interpreter/shared/src/test/scala/sigmastate/eval/BasicOpsTests.scala @@ -89,7 +89,7 @@ class BasicOpsTests extends AnyFunSuite with ContractsTestkit with Matchers { coster = accumulator, DefaultProfiler, es) val msg = Colls.fromArray(Base16.decode("0a101b8c6a4f2e").get) - VersionContext.withVersions(VersionContext.V6SoftForkVersion, VersionContext.V6SoftForkVersion) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { val res = MethodCall(Global, SGlobalMethods.xorMethod, IndexedSeq(ByteArrayConstant(msg), ByteArrayConstant(msg)), Map.empty) .evalTo[sigma.Coll[Byte]](Map.empty)(evaluator) @@ -125,7 +125,7 @@ class BasicOpsTests extends AnyFunSuite with ContractsTestkit with Matchers { constants = ErgoTree.EmptyConstants, coster = accumulator, DefaultProfiler, es) - VersionContext.withVersions(VersionContext.V6SoftForkVersion, VersionContext.V6SoftForkVersion) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { val res = MethodCall(Global, SGlobalMethods.powHitMethod, IndexedSeq(IntConstant(k), ByteArrayConstant(msg), ByteArrayConstant(nonce), ByteArrayConstant(hbs), IntConstant(N)), Map.empty) diff --git a/parsers/shared/src/test/scala/sigmastate/lang/LangTests.scala b/parsers/shared/src/test/scala/sigmastate/lang/LangTests.scala index de83070ac3..2aae13d13b 100644 --- a/parsers/shared/src/test/scala/sigmastate/lang/LangTests.scala +++ b/parsers/shared/src/test/scala/sigmastate/lang/LangTests.scala @@ -82,7 +82,7 @@ trait LangTests extends Matchers with NegativeTesting { /** Execute the given `block` having `version` as both activated and ErgoTree version. */ def runWithVersion[T](version: Byte)(block: => T): T = { - VersionContext.withVersions(version, version)(block) + VersionContext.withScriptVersion(version)(block) } } diff --git a/sc/shared/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala b/sc/shared/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala index d8ee6e3707..fca280cd9f 100644 --- a/sc/shared/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala +++ b/sc/shared/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala @@ -272,7 +272,7 @@ class ErgoAddressSpecification extends SigmaDslTesting property("Pay2SHAddress.script should create ErgoTree v0") { val (prop, _) = createPropAndScriptBytes() - val address = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val address = VersionContext.withScriptVersion(activatedVersionInTests) { Pay2SHAddress(prop) } address.script.version shouldBe 0 diff --git a/sc/shared/src/test/scala/sigma/LanguageSpecificationBase.scala b/sc/shared/src/test/scala/sigma/LanguageSpecificationBase.scala index 7be79546e7..20475e8e09 100644 --- a/sc/shared/src/test/scala/sigma/LanguageSpecificationBase.scala +++ b/sc/shared/src/test/scala/sigma/LanguageSpecificationBase.scala @@ -47,7 +47,7 @@ abstract class LanguageSpecificationBase extends SigmaDslTesting * parameters. */ protected override def testFun_Run(testName: String, testFun: => Any): Unit = { - VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + VersionContext.withScriptVersion(activatedVersionInTests) { super.testFun_Run(testName, testFun) } } diff --git a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala index 7f3f28b791..488071a700 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala @@ -527,11 +527,11 @@ class SigmaDslTesting extends AnyPropSpec */ def checkEquality(input: A, logInputOutput: Boolean = false): Try[(B, CostDetails)] = { // check the old implementation against Scala semantic function - val oldRes = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val oldRes = VersionContext.withScriptVersion(activatedVersionInTests) { checkEq(scalaFunc)(oldF)(input) } - val newRes = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val newRes = VersionContext.withScriptVersion(activatedVersionInTests) { checkEq(scalaFunc)({ x => var y: (B, CostDetails) = null val N = nBenchmarkIters + 1 @@ -588,13 +588,13 @@ class SigmaDslTesting extends AnyPropSpec */ override def checkExpected(input: A, expected: Expected[B]): Unit = { // check the old implementation with Scala semantic - val (oldRes, _) = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val (oldRes, _) = VersionContext.withScriptVersion(activatedVersionInTests) { checkEq(scalaFunc)(oldF)(input).get } oldRes shouldBe expected.value.get // check the new implementation with Scala semantic - val (newRes, newDetails) = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val (newRes, newDetails) = VersionContext.withScriptVersion(activatedVersionInTests) { checkEq(scalaFunc)(newF)(input).get } newRes shouldBe expected.value.get @@ -716,7 +716,7 @@ class SigmaDslTesting extends AnyPropSpec override def checkEquality(input: A, logInputOutput: Boolean = false): Try[(B, CostDetails)] = { // check the old implementation against Scala semantic function var oldRes: Try[(B, CostDetails)] = null - oldRes = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + oldRes = VersionContext.withScriptVersion(activatedVersionInTests) { try checkEq(scalaFunc)(oldF)(input) catch { case e: TestFailedException => @@ -734,7 +734,7 @@ class SigmaDslTesting extends AnyPropSpec val newRes = { // check the new implementation against Scala semantic function - val newRes = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val newRes = VersionContext.withScriptVersion(activatedVersionInTests) { checkEq(scalaFuncNew)(newF)(input) } if (ergoTreeVersionInTests < VersionContext.JitActivationVersion) { @@ -770,7 +770,7 @@ class SigmaDslTesting extends AnyPropSpec */ override def checkExpected(input: A, expected: Expected[B]): Unit = { // check the new implementation with Scala semantic function - val newRes = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val newRes = VersionContext.withScriptVersion(activatedVersionInTests) { checkEq(scalaFuncNew)(newF)(input) } @@ -910,7 +910,7 @@ class SigmaDslTesting extends AnyPropSpec override def checkExpected(input: A, expected: Expected[B]): Unit = { Try(oldF(input)).isFailure shouldBe true if (!(newImpl eq oldImpl)) { - val (newRes, _) = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val (newRes, _) = VersionContext.withScriptVersion(activatedVersionInTests) { checkEq(scalaFuncNew)(newF)(input).get } val newExpectedRes = expected.newResults(ergoTreeVersionInTests) @@ -1264,7 +1264,7 @@ class SigmaDslTesting extends AnyPropSpec val funcNoTrace = funcJit[A, B](f.script)(tA, tB, IR, noTraceSettings, cs) var iCase = 0 val (res, total) = BenchmarkUtil.measureTimeNano { - VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + VersionContext.withScriptVersion(activatedVersionInTests) { cases.map { x => assert(func(x)._1 == f.newF(x)._1) iCase += 1 diff --git a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala index 0504a79c65..985826879a 100644 --- a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala @@ -696,12 +696,12 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit with C val expr = Apply(FuncValue(Vector(), IntConstant(1)), IndexedSeq()) forEachScriptAndErgoTreeVersion(activatedVersions, ergoTreeVersions) { - VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + VersionContext.withScriptVersion(activatedVersionInTests) { val newF = funcJitFromExpr[Int, Int]("({ (x: Int) => 1 })()", expr) assertExceptionThrown( { val x = 100 // any value which is not used anyway - val _ = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val _ = VersionContext.withScriptVersion(activatedVersionInTests) { newF.apply(x) } }, @@ -721,9 +721,9 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit with C val x = 1 forEachScriptAndErgoTreeVersion(activatedVersions, ergoTreeVersions) { - VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + VersionContext.withScriptVersion(activatedVersionInTests) { val newF = funcJitFromExpr[Int, Int](script, expr) - val (y, _) = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val (y, _) = VersionContext.withScriptVersion(activatedVersionInTests) { newF.apply(x) } y shouldBe -1 @@ -739,11 +739,11 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit with C val script = "{ (x: Int, y: Int) => x + y }" forEachScriptAndErgoTreeVersion(activatedVersions, ergoTreeVersions) { - VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + VersionContext.withScriptVersion(activatedVersionInTests) { val newF = funcJitFromExpr[(Int, Int), Int](script, expr) assertExceptionThrown( { - val _ = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + val _ = VersionContext.withScriptVersion(activatedVersionInTests) { newF.apply((1, 1)) } }, @@ -840,7 +840,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit with C forEachScriptAndErgoTreeVersion( activatedVers = Array(JitActivationVersion), ergoTreeVers = ergoTreeVersions) { - VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + VersionContext.withScriptVersion(activatedVersionInTests) { { // depth 3 val cf = mkCompiledFunc(3) @@ -950,13 +950,13 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit with C .dummy(fakeSelf, VersionContext.current.activatedVersion) .withErgoTreeVersion(tree.version) - VersionContext.withVersions(activatedVersion = 1, tree.version) { + VersionContext.withScriptVersion(activatedVersion = 1) { // v4.x behavior val res = CErgoTreeEvaluator.evalToCrypto(createCtx, tree, evalSettings) res shouldBe ReductionResult(TrivialProp(true), 3) } - VersionContext.withVersions(activatedVersion = 2, tree.version) { + VersionContext.withScriptVersion(activatedVersion = 2) { // v5.0 behavior assertExceptionThrown( CErgoTreeEvaluator.evalToCrypto(createCtx, tree, evalSettings), diff --git a/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala b/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala index da9ed70efd..c36ccaa852 100644 --- a/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala +++ b/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala @@ -188,7 +188,7 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests if (ergoCtx.isDefined) { val ectx = ergoCtx.get.withErgoTreeVersion(ergoTreeVersionInTests) - VersionContext.withVersions(ectx.activatedScriptVersion, ergoTreeVersionInTests) { + VersionContext.withScriptVersion(ectx.activatedScriptVersion) { val calcCtx = ectx.toSigmaContext() val testContractRes = testContract.map(_(calcCtx)) testContractRes.foreach { res => diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 2194414ab0..ea4d64c2c1 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -16,7 +16,7 @@ import scorex.utils.Longs import sigma.{Colls, SigmaTestingData} import sigma.Extensions.ArrayOps import sigma.{SigmaTestingData, VersionContext} -import sigma.VersionContext.{V6SoftForkVersion, withVersions} +import sigma.VersionContext.{V6SoftForkVersion, withScriptVersion} import sigma.VersionContext.V6SoftForkVersion import sigma.VersionContext import sigma.GroupElement @@ -127,7 +127,7 @@ class BasicOpsSpecification extends CompilerTestingCommons propExp.asSigmaProp } else { // compile with the latest compiler version, to get validation exception during execution, not compilation error - withVersions(VersionContext.MaxSupportedScriptVersion, ergoTreeVersionInTests) { + withScriptVersion(VersionContext.MaxSupportedScriptVersion) { compile(env, script).asBoolValue.toSigmaProp } } diff --git a/sdk/shared/src/main/scala/org/ergoplatform/sdk/AppkitProvingInterpreter.scala b/sdk/shared/src/main/scala/org/ergoplatform/sdk/AppkitProvingInterpreter.scala index c0dc075a9b..b2931d1eba 100644 --- a/sdk/shared/src/main/scala/org/ergoplatform/sdk/AppkitProvingInterpreter.scala +++ b/sdk/shared/src/main/scala/org/ergoplatform/sdk/AppkitProvingInterpreter.scala @@ -340,7 +340,7 @@ object ReducedErgoLikeTransactionSerializer extends SigmaSerializer[ReducedErgoL */ def parse(r: SigmaByteReader, blockVersion: Byte): ReducedErgoLikeTransaction = { val scriptVersion = (blockVersion - 1).toByte - VersionContext.withVersions(scriptVersion, scriptVersion) { + VersionContext.withScriptVersion(scriptVersion) { parse(r) } } diff --git a/sdk/shared/src/test/scala/org/ergoplatform/sdk/DataJsonEncoderSpecification.scala b/sdk/shared/src/test/scala/org/ergoplatform/sdk/DataJsonEncoderSpecification.scala index 7e73b6c93d..1eebc9c1ba 100644 --- a/sdk/shared/src/test/scala/org/ergoplatform/sdk/DataJsonEncoderSpecification.scala +++ b/sdk/shared/src/test/scala/org/ergoplatform/sdk/DataJsonEncoderSpecification.scala @@ -31,7 +31,7 @@ class DataJsonEncoderSpecification extends SerializationSpecification { withVersion match { case Some(ver) => - VersionContext.withVersions(ver, 0) { + VersionContext.withScriptVersion(ver) { test() } case None => @@ -221,7 +221,7 @@ class DataJsonEncoderSpecification extends SerializationSpecification { } if (tpe == SHeader) { - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 0) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { test() } } else { @@ -232,7 +232,7 @@ class DataJsonEncoderSpecification extends SerializationSpecification { property("AnyValue") { forAll { t: SPredefType => if (t == SHeader) { - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withScriptVersion(VersionContext.V6SoftForkVersion) { testAnyValue(t) testAnyValue(SOption(t)) } From 22ce03bf0146217f1be3a7dc851c15cfaa8711e3 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 6 Dec 2024 23:50:11 +0300 Subject: [PATCH 09/25] unused env removed from reductionWithDeserialize --- data/shared/src/main/scala/sigma/ast/ErgoTree.scala | 3 ++- .../main/scala/sigma/serialization/ErgoTreeSerializer.scala | 2 +- .../src/main/scala/sigmastate/interpreter/Interpreter.scala | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/shared/src/main/scala/sigma/ast/ErgoTree.scala b/data/shared/src/main/scala/sigma/ast/ErgoTree.scala index 8d731e1c67..ec902a20eb 100644 --- a/data/shared/src/main/scala/sigma/ast/ErgoTree.scala +++ b/data/shared/src/main/scala/sigma/ast/ErgoTree.scala @@ -375,7 +375,7 @@ object ErgoTree { * 3) write the `tree` to the Writer's buffer obtaining `treeBytes`; * 4) deserialize `tree` with ConstantPlaceholders. * - * @param headerFlags additional header flags to combine with + * @param header additional header flags to combine with * ConstantSegregationHeader flag. * @param prop expression to be transformed into ErgoTree * */ @@ -411,4 +411,5 @@ object ErgoTree { def fromBytes(bytes: Array[Byte]): ErgoTree = { ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes) } + } diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 1d14fcdc6b..affba713fc 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -74,7 +74,7 @@ import sigma.validation.ValidationRules.CheckPositionLimit * End of proof. * */ -class ErgoTreeSerializer(protocolVersion: Byte = VersionContext.V6SoftForkVersion) { +class ErgoTreeSerializer { /** Serialize header and constants section only.*/ private def serializeHeader(ergoTree: ErgoTree, w: SigmaByteWriter): Unit = { diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala index a9474d0c6b..822bb8c351 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -239,8 +239,7 @@ trait Interpreter { /** Performs reduction of proposition which contains deserialization operations. */ private def reductionWithDeserialize(ergoTree: ErgoTree, prop: SigmaPropValue, - context: CTX, - env: ScriptEnv): ReductionResult = { + context: CTX): ReductionResult = { implicit val vs: SigmaValidationSettings = context.validationSettings val res = VersionContext.withScriptVersion(context.activatedScriptVersion) { val deserializeSubstitutionCost = java7.compat.Math.multiplyExact(ergoTree.bytes.length, CostPerTreeByte) From e2720be8e5182bf32885bd568b91a52b61b5aabb Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 11 Dec 2024 13:12:45 +0300 Subject: [PATCH 10/25] tree version based checks for lazy default --- core/shared/src/main/scala/sigma/VersionContext.scala | 5 +++++ data/shared/src/main/scala/sigma/ast/transformers.scala | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 6ede0a1556..770323704f 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -25,6 +25,11 @@ case class VersionContext(activatedVersion: Byte, ergoTreeVersion: Byte) { /** @return true, if the activated script version of Ergo protocol on the network is * including v6.0 update. */ def isV6SoftForkActivated: Boolean = activatedVersion >= V6SoftForkVersion + + def isV6SoftForkActivatedAndTreeV3: Boolean = { + activatedVersion >= V6SoftForkVersion && ergoTreeVersion >= V6SoftForkVersion + } + } object VersionContext { diff --git a/data/shared/src/main/scala/sigma/ast/transformers.scala b/data/shared/src/main/scala/sigma/ast/transformers.scala index 8d7e689a18..d68f684693 100644 --- a/data/shared/src/main/scala/sigma/ast/transformers.scala +++ b/data/shared/src/main/scala/sigma/ast/transformers.scala @@ -258,7 +258,7 @@ case class ByIndex[V <: SType](input: Value[SCollection[V]], val indexV = index.evalTo[Int](env) default match { case Some(d) => - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV6SoftForkActivatedAndTreeV3) { // lazy evaluation of default in 6.0 addCost(ByIndex.costKind) if (inputV.isDefinedAt(indexV)) { @@ -625,7 +625,7 @@ case class OptionGetOrElse[V <: SType](input: Value[SOption[V]], default: Value[ override val opType = SFunc(IndexedSeq(input.tpe, tpe), tpe) override def tpe: V = input.tpe.elemType protected final override def eval(env: DataEnv)(implicit E: ErgoTreeEvaluator): Any = { - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV6SoftForkActivatedAndTreeV3) { // lazy evaluation of default in 6.0 val inputV = input.evalTo[Option[V#WrappedType]](env) addCost(OptionGetOrElse.costKind) From 59225d3ca91c8d6d57020274fc959f6fe8d05497 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 13 Dec 2024 16:34:50 +0300 Subject: [PATCH 11/25] tree version based versioning --- .../src/main/scala/sigma/VersionContext.scala | 6 +- .../src/main/scala/sigma/ast/SType.scala | 26 +- .../scala/sigma/data/CollsOverArrays.scala | 4 +- .../serialization/CoreDataSerializer.scala | 8 +- .../sigma/serialization/TypeSerializer.scala | 4 +- data/js/src/main/scala/sigma/Platform.scala | 26 +- data/jvm/src/main/scala/sigma/Platform.scala | 28 +- .../src/main/scala/sigma/ast/methods.scala | 22 +- .../main/scala/sigma/ast/transformers.scala | 4 +- .../sigma/serialization/DataSerializer.scala | 4 +- .../serialization/ErgoTreeSerializer.scala | 2 +- .../scala/sigma/ast/SigmaBuilderTest.scala | 22 +- .../generators/ObjectGenerators.scala | 2 +- .../generators/TypeGenerators.scala | 4 +- .../sigma/compiler/ir/GraphBuilding.scala | 16 +- .../ErgoLikeTransactionSpec.scala | 2 +- .../scala/sigma/LanguageSpecificationV5.scala | 4 +- .../scala/sigma/LanguageSpecificationV6.scala | 51 +++- .../test/scala/sigma/SigmaDslTesting.scala | 27 +- .../sigmastate/ErgoTreeSpecification.scala | 6 +- .../TestingInterpreterSpecification.scala | 8 +- .../utxo/BasicOpsSpecification.scala | 256 +++++++++--------- 22 files changed, 285 insertions(+), 247 deletions(-) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 770323704f..6c7ffd0720 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -24,11 +24,7 @@ case class VersionContext(activatedVersion: Byte, ergoTreeVersion: Byte) { /** @return true, if the activated script version of Ergo protocol on the network is * including v6.0 update. */ - def isV6SoftForkActivated: Boolean = activatedVersion >= V6SoftForkVersion - - def isV6SoftForkActivatedAndTreeV3: Boolean = { - activatedVersion >= V6SoftForkVersion && ergoTreeVersion >= V6SoftForkVersion - } + def isV3OrLaterErgoTreeVersion: Boolean = ergoTreeVersion >= V6SoftForkVersion } diff --git a/core/shared/src/main/scala/sigma/ast/SType.scala b/core/shared/src/main/scala/sigma/ast/SType.scala index 3e915cf304..a87b9a8076 100644 --- a/core/shared/src/main/scala/sigma/ast/SType.scala +++ b/core/shared/src/main/scala/sigma/ast/SType.scala @@ -114,7 +114,7 @@ object SType { /** All pre-defined types should be listed here. Note, NoType is not listed. * Should be in sync with sigmastate.lang.Types.predefTypes. */ def allPredefTypes: Seq[SType] = { - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { v6PredefTypes } else { v5PredefTypes @@ -164,7 +164,7 @@ object SType { private val v6TypesMap = v6Types.map { t => (t.typeId, t) }.toMap - def types: Map[Byte, STypeCompanion] = if (VersionContext.current.isV6SoftForkActivated) { + def types: Map[Byte, STypeCompanion] = if (VersionContext.current.isV3OrLaterErgoTreeVersion) { v6TypesMap } else { v5TypesMap @@ -191,7 +191,7 @@ object SType { case SInt => x.isInstanceOf[Int] case SLong => x.isInstanceOf[Long] case SBigInt => x.isInstanceOf[BigInt] - case SUnsignedBigInt if VersionContext.current.isV6SoftForkActivated => x.isInstanceOf[UnsignedBigInt] + case SUnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => x.isInstanceOf[UnsignedBigInt] case SGroupElement => x.isInstanceOf[GroupElement] case SSigmaProp => x.isInstanceOf[SigmaProp] case SBox => x.isInstanceOf[Box] @@ -409,8 +409,8 @@ case object SByte extends SPrimType with SEmbeddable with SNumericType with SMon case s: Short => s.toByteExact case i: Int => i.toByteExact case l: Long => l.toByteExact - case bi: BigInt if VersionContext.current.isV6SoftForkActivated => bi.toByte // toByteExact from int is called under the hood - case ubi: UnsignedBigInt if VersionContext.current.isV6SoftForkActivated => ubi.toByte // toByteExact from int is called under the hood + case bi: BigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => bi.toByte // toByteExact from int is called under the hood + case ubi: UnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => ubi.toByte // toByteExact from int is called under the hood case _ => sys.error(s"Cannot downcast value $v to the type $this") } } @@ -432,8 +432,8 @@ case object SShort extends SPrimType with SEmbeddable with SNumericType with SMo case s: Short => s case i: Int => i.toShortExact case l: Long => l.toShortExact - case bi: BigInt if VersionContext.current.isV6SoftForkActivated => bi.toShort // toShortExact from int is called under the hood - case ubi: UnsignedBigInt if VersionContext.current.isV6SoftForkActivated => ubi.toShort // toShortExact from int is called under the hood + case bi: BigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => bi.toShort // toShortExact from int is called under the hood + case ubi: UnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => ubi.toShort // toShortExact from int is called under the hood case _ => sys.error(s"Cannot downcast value $v to the type $this") } } @@ -457,8 +457,8 @@ case object SInt extends SPrimType with SEmbeddable with SNumericType with SMono case s: Short => s.toInt case i: Int => i case l: Long => l.toIntExact - case bi: BigInt if VersionContext.current.isV6SoftForkActivated => bi.toInt - case ubi: UnsignedBigInt if VersionContext.current.isV6SoftForkActivated => ubi.toInt + case bi: BigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => bi.toInt + case ubi: UnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => ubi.toInt case _ => sys.error(s"Cannot downcast value $v to the type $this") } } @@ -484,8 +484,8 @@ case object SLong extends SPrimType with SEmbeddable with SNumericType with SMon case s: Short => s.toLong case i: Int => i.toLong case l: Long => l - case bi: BigInt if VersionContext.current.isV6SoftForkActivated => bi.toLong - case ubi: UnsignedBigInt if VersionContext.current.isV6SoftForkActivated => ubi.toLong + case bi: BigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => bi.toLong + case ubi: UnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => ubi.toLong case _ => sys.error(s"Cannot downcast value $v to the type $this") } } @@ -512,7 +512,7 @@ case object SBigInt extends SPrimType with SEmbeddable with SNumericType with SM case x: Short => CBigInt(BigInteger.valueOf(x.toLong)) case x: Int => CBigInt(BigInteger.valueOf(x.toLong)) case x: Long => CBigInt(BigInteger.valueOf(x)) - case x: BigInt if VersionContext.current.isV6SoftForkActivated => x + case x: BigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => x case _ => sys.error(s"Cannot upcast value $v to the type $this") } } @@ -524,7 +524,7 @@ case object SBigInt extends SPrimType with SEmbeddable with SNumericType with SM case x: Short => CBigInt(BigInteger.valueOf(x.toLong)) case x: Int => CBigInt(BigInteger.valueOf(x.toLong)) case x: Long => CBigInt(BigInteger.valueOf(x)) - case x: BigInt if VersionContext.current.isV6SoftForkActivated => x + case x: BigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => x case _ => sys.error(s"Cannot downcast value $v to the type $this") } } diff --git a/core/shared/src/main/scala/sigma/data/CollsOverArrays.scala b/core/shared/src/main/scala/sigma/data/CollsOverArrays.scala index 2d6a4a5cdf..dbaa430b69 100644 --- a/core/shared/src/main/scala/sigma/data/CollsOverArrays.scala +++ b/core/shared/src/main/scala/sigma/data/CollsOverArrays.scala @@ -150,7 +150,7 @@ class CollOverArray[@specialized A](val toArray: Array[A], val builder: CollBuil case obj: CollOverArray[_] if obj.tItem == this.tItem => java.util.Objects.deepEquals(obj.toArray, this.toArray) case obj: PairColl[Any, Any] if obj.tItem == this.tItem => - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { equalsPairCollWithCollOverArray(obj, this.asInstanceOf[CollOverArray[Any]]) } else { false @@ -282,7 +282,7 @@ class PairOfCols[@specialized L, @specialized R](val ls: Coll[L], val rs: Coll[R case that: PairColl[_, _] if that.tItem == this.tItem => ls == that.ls && rs == that.rs case that: CollOverArray[Any] if that.tItem == this.tItem => - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { equalsPairCollWithCollOverArray(this.asInstanceOf[PairColl[Any, Any]], that) } else { false diff --git a/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala b/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala index 175e91fbcb..1f6f95b471 100644 --- a/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala +++ b/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala @@ -34,7 +34,7 @@ class CoreDataSerializer { val data = v.asInstanceOf[BigInt].toBigInteger.toByteArray w.putUShort(data.length) w.putBytes(data) - case SUnsignedBigInt if VersionContext.current.isV6SoftForkActivated => + case SUnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => val data = BigIntegers.asUnsignedByteArray(v.asInstanceOf[CUnsignedBigInt].wrappedValue) w.putUShort(data.length) w.putBytes(data) @@ -73,7 +73,7 @@ class CoreDataSerializer { i += 1 } - case SOption(elemType) if VersionContext.current.isV6SoftForkActivated => + case SOption(elemType) if VersionContext.current.isV3OrLaterErgoTreeVersion => val o = v.asInstanceOf[Option[elemType.WrappedType]] w.putOption(o){case (w, v) => serialize(v, elemType, w) @@ -113,7 +113,7 @@ class CoreDataSerializer { } val valueBytes = r.getBytes(size) CBigInt(new BigInteger(valueBytes)) - case SUnsignedBigInt if VersionContext.current.isV6SoftForkActivated => + case SUnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => val size: Short = r.getUShort().toShort if (size > SBigInt.MaxSizeInBytes) { throw SerializerException(s"BigInt value doesn't not fit into ${SBigInt.MaxSizeInBytes} bytes: $size") @@ -135,7 +135,7 @@ class CoreDataSerializer { }.toArray[Any] val coll = Colls.fromArray(arr)(sigma.AnyType) Evaluation.toDslTuple(coll, tuple) - case tOption: SOption[_] if VersionContext.current.isV6SoftForkActivated => + case tOption: SOption[_] if VersionContext.current.isV3OrLaterErgoTreeVersion => r.getOption[tOption.ElemWrappedType] { deserialize(tOption.elemType, r).asInstanceOf[tOption.ElemWrappedType] } diff --git a/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala b/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala index aa5d43e229..ec2af27aca 100644 --- a/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala +++ b/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala @@ -200,7 +200,7 @@ class TypeSerializer { case SHeader.typeCode => SHeader case SPreHeader.typeCode => SPreHeader case SGlobal.typeCode => SGlobal - case SFunc.FuncTypeCode if VersionContext.current.isV6SoftForkActivated => + case SFunc.FuncTypeCode if VersionContext.current.isV3OrLaterErgoTreeVersion => val tdLength = r.getUByte() val tDom = (1 to tdLength).map { _ => @@ -243,7 +243,7 @@ object TypeSerializer extends TypeSerializer { /** The list of embeddable types, i.e. types that can be combined with type constructor for optimized encoding. * For each embeddable type `T`, and type constructor `C`, the type `C[T]` can be represented by single byte. */ def embeddableIdToType = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { embeddableV6 } else { embeddableV5 diff --git a/data/js/src/main/scala/sigma/Platform.scala b/data/js/src/main/scala/sigma/Platform.scala index 63c2ab5555..9db049b368 100644 --- a/data/js/src/main/scala/sigma/Platform.scala +++ b/data/js/src/main/scala/sigma/Platform.scala @@ -14,33 +14,33 @@ object Platform { private[sigma] def liftToConstant(obj: Any, builder: SigmaBuilder): Nullable[Constant[SType]] = { import builder._ obj match { - case arr: Array[Boolean] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SBoolean.type](arr, SBoolean)) - case arr: Array[Byte] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SByte.type](arr, SByte)) - case arr: Array[Short] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SShort.type](arr, SShort)) - case arr: Array[Int] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SInt.type](arr, SInt)) - case arr: Array[Long] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SLong.type](arr, SLong)) - case arr: Array[BigInteger] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SBigInt.type](arr.map[BigInt](n => CBigInt(n)), SBigInt)) - case arr: Array[String] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SString.type](arr, SString)) + case arr: Array[Boolean] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SBoolean.type](arr, SBoolean)) + case arr: Array[Byte] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SByte.type](arr, SByte)) + case arr: Array[Short] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SShort.type](arr, SShort)) + case arr: Array[Int] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SInt.type](arr, SInt)) + case arr: Array[Long] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SLong.type](arr, SLong)) + case arr: Array[BigInteger] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SBigInt.type](arr.map[BigInt](n => CBigInt(n)), SBigInt)) + case arr: Array[String] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SString.type](arr, SString)) case v: AnyValue => val tpe = Evaluation.rtypeToSType(v.tVal) Nullable(mkConstant[tpe.type](v.value.asInstanceOf[tpe.WrappedType], tpe)) case v: Int => Nullable(mkConstant[SInt.type](v, SInt)) case v: Long => Nullable(mkConstant[SLong.type](v, SLong)) - case v: BigInteger if !VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SBigInt.type](CBigInt(v), SBigInt)) + case v: BigInteger if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SBigInt.type](CBigInt(v), SBigInt)) case n: sigma.BigInt => Nullable(mkConstant[SBigInt.type](n, SBigInt)) case n: sigma.UnsignedBigInt => Nullable(mkConstant[SUnsignedBigInt.type](n, SUnsignedBigInt)) case ge: GroupElement => Nullable(mkConstant[SGroupElement.type](ge, SGroupElement)) case b: Boolean => Nullable(if (b) TrueLeaf else FalseLeaf) - case v: String if !VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SString.type](v, SString)) - case h: Header if VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SHeader.type](h, SHeader)) - case h: PreHeader if VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SPreHeader.type](h, SPreHeader)) + case v: String if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SString.type](v, SString)) + case h: Header if VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SHeader.type](h, SHeader)) + case h: PreHeader if VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SPreHeader.type](h, SPreHeader)) // The Box lifting was broken in v4.x. `SigmaDsl.Box(b)` was missing which means the // isCorrectType requirement would fail in ConstantNode constructor. // This method is used as part of consensus in SubstConstants operation, however // ErgoBox cannot be passed as argument as it is never valid value during evaluation. // Thus we can use activation-based versioning and fix this code when v5.0 is activated. - case b: ErgoBox if !VersionContext.current.isV6SoftForkActivated => + case b: ErgoBox if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SBox.type](CBox(b), SBox)) // fixed in v5.0 // this case is added in v5.0 and it can be useful when the box value comes from a @@ -50,7 +50,7 @@ object Platform { Nullable(mkConstant[SBox.type](b, SBox)) else Nullable.None // return the same result as in v4.x when there was no this case - case avl: AvlTreeData if !VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SAvlTree.type](CAvlTree(avl), SAvlTree)) + case avl: AvlTreeData if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SAvlTree.type](CAvlTree(avl), SAvlTree)) case avl: AvlTree => Nullable(mkConstant[SAvlTree.type](avl, SAvlTree)) case sb: SigmaBoolean => Nullable(mkConstant[SSigmaProp.type](CSigmaProp(sb), SSigmaProp)) case p: SigmaProp => Nullable(mkConstant[SSigmaProp.type](p, SSigmaProp)) diff --git a/data/jvm/src/main/scala/sigma/Platform.scala b/data/jvm/src/main/scala/sigma/Platform.scala index 8fc5019bf9..178ae242c7 100644 --- a/data/jvm/src/main/scala/sigma/Platform.scala +++ b/data/jvm/src/main/scala/sigma/Platform.scala @@ -16,33 +16,33 @@ object Platform { private[sigma] def liftToConstant(obj: Any, builder: SigmaBuilder): Nullable[Constant[SType]] = { import builder._ obj match { - case arr: Array[Boolean] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SBoolean.type](arr, SBoolean)) - case arr: Array[Byte] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SByte.type](arr, SByte)) - case arr: Array[Short] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SShort.type](arr, SShort)) - case arr: Array[Int] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SInt.type](arr, SInt)) - case arr: Array[Long] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SLong.type](arr, SLong)) - case arr: Array[BigInteger] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SBigInt.type](arr.map(SigmaDsl.BigInt(_)), SBigInt)) - case arr: Array[String] if !VersionContext.current.isV6SoftForkActivated => Nullable(mkCollectionConstant[SString.type](arr, SString)) + case arr: Array[Boolean] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SBoolean.type](arr, SBoolean)) + case arr: Array[Byte] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SByte.type](arr, SByte)) + case arr: Array[Short] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SShort.type](arr, SShort)) + case arr: Array[Int] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SInt.type](arr, SInt)) + case arr: Array[Long] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SLong.type](arr, SLong)) + case arr: Array[BigInteger] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SBigInt.type](arr.map(SigmaDsl.BigInt(_)), SBigInt)) + case arr: Array[String] if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkCollectionConstant[SString.type](arr, SString)) case v: Byte => Nullable(mkConstant[SByte.type](v, SByte)) case v: Short => Nullable(mkConstant[SShort.type](v, SShort)) case v: Int => Nullable(mkConstant[SInt.type](v, SInt)) case v: Long => Nullable(mkConstant[SLong.type](v, SLong)) - case v: BigInteger if !VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SBigInt.type](SigmaDsl.BigInt(v), SBigInt)) + case v: BigInteger if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SBigInt.type](SigmaDsl.BigInt(v), SBigInt)) case n: sigma.BigInt => Nullable(mkConstant[SBigInt.type](n, SBigInt)) case ge: GroupElement => Nullable(mkConstant[SGroupElement.type](ge, SGroupElement)) case b: Boolean => Nullable(if (b) TrueLeaf else FalseLeaf) - case h: Header if VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SHeader.type](h, SHeader)) - case h: PreHeader if VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SPreHeader.type](h, SPreHeader)) - case n: sigma.UnsignedBigInt if VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SUnsignedBigInt.type](n, SUnsignedBigInt)) + case h: Header if VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SHeader.type](h, SHeader)) + case h: PreHeader if VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SPreHeader.type](h, SPreHeader)) + case n: sigma.UnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SUnsignedBigInt.type](n, SUnsignedBigInt)) - case v: String if !VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SString.type](v, SString)) + case v: String if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SString.type](v, SString)) // The Box lifting was broken in v4.x. `SigmaDsl.Box(b)` was missing which means the // isCorrectType requirement would fail in ConstantNode constructor. // This method is used as part of consensus in SubstConstants operation, however // ErgoBox cannot be passed as argument as it is never valid value during evaluation. // Thus we can use activation-based versioning and fix this code when v5.0 is activated. - case b: ErgoBox if !VersionContext.current.isV6SoftForkActivated => + case b: ErgoBox if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SBox.type](SigmaDsl.Box(b), SBox)) // fixed in v5.0 // this case is added in v5.0 and it can be useful when the box value comes from a @@ -52,7 +52,7 @@ object Platform { Nullable(mkConstant[SBox.type](b, SBox)) else Nullable.None // return the same result as in v4.x when there was no this case - case avl: AvlTreeData if !VersionContext.current.isV6SoftForkActivated => Nullable(mkConstant[SAvlTree.type](SigmaDsl.avlTree(avl), SAvlTree)) + case avl: AvlTreeData if !VersionContext.current.isV3OrLaterErgoTreeVersion => Nullable(mkConstant[SAvlTree.type](SigmaDsl.avlTree(avl), SAvlTree)) case avl: AvlTree => Nullable(mkConstant[SAvlTree.type](avl, SAvlTree)) case sb: SigmaBoolean => Nullable(mkConstant[SSigmaProp.type](SigmaDsl.SigmaProp(sb), SSigmaProp)) case p: SigmaProp => Nullable(mkConstant[SSigmaProp.type](p, SSigmaProp)) diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index a69654de7e..1f800a68fc 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -132,7 +132,7 @@ object MethodsContainer { private val containersV6 = new SparseArrayContainer[MethodsContainer](methodsV6.map(m => (m.typeId, m))) def contains(typeId: TypeCode): Boolean = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { containersV6.contains(typeId) } else { containersV5.contains(typeId) @@ -140,7 +140,7 @@ object MethodsContainer { } def apply(typeId: TypeCode): MethodsContainer = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { containersV6(typeId) } else { containersV5(typeId) @@ -157,7 +157,7 @@ object MethodsContainer { case tup: STuple => STupleMethods.getTupleMethod(tup, methodName) case _ => - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { containersV6.get(tpe.typeCode).flatMap(_.method(methodName)) } else { containersV5.get(tpe.typeCode).flatMap(_.method(methodName)) @@ -208,7 +208,7 @@ trait SNumericTypeMethods extends MonoTypeMethods { } protected override def getMethods(): Seq[SMethod] = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { super.getMethods() ++ v6Methods } else { super.getMethods() ++ v5Methods @@ -523,7 +523,7 @@ case object SBigIntMethods extends SNumericTypeMethods { ArgInfo("m", "modulo value")) protected override def getMethods(): Seq[SMethod] = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { super.getMethods() ++ Seq(ToUnsigned, ToUnsignedMod) } else { super.getMethods() @@ -651,7 +651,7 @@ case object SGroupElementMethods extends MonoTypeMethods { MultiplyMethod, NegateMethod) - super.getMethods() ++ (if (VersionContext.current.isV6SoftForkActivated) { + super.getMethods() ++ (if (VersionContext.current.isV3OrLaterErgoTreeVersion) { v5Methods ++ Seq(ExponentiateUnsignedMethod) } else { v5Methods @@ -1309,7 +1309,7 @@ object SCollectionMethods extends MethodsContainer with MethodByNameUnapply { * Typical override: `super.getMethods() ++ Seq(m1, m2, m3)` */ override protected def getMethods(): Seq[SMethod] = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { v6Methods } else { v5Methods @@ -1462,7 +1462,7 @@ case object SBoxMethods extends MonoTypeMethods { // should be lazy to solve recursive initialization protected override def getMethods() = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { v6Methods } else { v5Methods @@ -1837,7 +1837,7 @@ case object SContextMethods extends MonoTypeMethods { ) protected override def getMethods(): Seq[SMethod] = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { v6Methods } else { v5Methods @@ -1888,7 +1888,7 @@ case object SHeaderMethods extends MonoTypeMethods { private lazy val v6Methods = v5Methods ++ Seq(checkPowMethod) protected override def getMethods() = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { v6Methods } else { v5Methods @@ -2061,7 +2061,7 @@ case object SGlobalMethods extends MonoTypeMethods { .withInfo(MethodCall, "Returns empty Option[T] of given type T.") protected override def getMethods() = super.getMethods() ++ { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { Seq( groupGeneratorMethod, xorMethod, diff --git a/data/shared/src/main/scala/sigma/ast/transformers.scala b/data/shared/src/main/scala/sigma/ast/transformers.scala index d68f684693..9c622ca2da 100644 --- a/data/shared/src/main/scala/sigma/ast/transformers.scala +++ b/data/shared/src/main/scala/sigma/ast/transformers.scala @@ -258,7 +258,7 @@ case class ByIndex[V <: SType](input: Value[SCollection[V]], val indexV = index.evalTo[Int](env) default match { case Some(d) => - if (VersionContext.current.isV6SoftForkActivatedAndTreeV3) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { // lazy evaluation of default in 6.0 addCost(ByIndex.costKind) if (inputV.isDefinedAt(indexV)) { @@ -625,7 +625,7 @@ case class OptionGetOrElse[V <: SType](input: Value[SOption[V]], default: Value[ override val opType = SFunc(IndexedSeq(input.tpe, tpe), tpe) override def tpe: V = input.tpe.elemType protected final override def eval(env: DataEnv)(implicit E: ErgoTreeEvaluator): Any = { - if(VersionContext.current.isV6SoftForkActivatedAndTreeV3) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { // lazy evaluation of default in 6.0 val inputV = input.evalTo[Option[V#WrappedType]](env) addCost(OptionGetOrElse.costKind) diff --git a/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala b/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala index 92a54f9aa4..4955db5bdc 100644 --- a/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala @@ -16,7 +16,7 @@ object DataSerializer extends CoreDataSerializer { case SBox => val b = v.asInstanceOf[CBox] ErgoBox.sigmaSerializer.serialize(b.ebox, w.asInstanceOf[SigmaByteWriter]) - case SHeader if VersionContext.current.isV6SoftForkActivated => + case SHeader if VersionContext.current.isV3OrLaterErgoTreeVersion => val h = v.asInstanceOf[CHeader] ErgoHeader.sigmaSerializer.serialize(h.ergoHeader, w.asInstanceOf[SigmaByteWriter]) case _ => @@ -36,7 +36,7 @@ object DataSerializer extends CoreDataSerializer { val res = CBox(ErgoBox.sigmaSerializer.parse(r.asInstanceOf[SigmaByteReader])) r.level = r.level - 1 res - case SHeader if VersionContext.current.isV6SoftForkActivated => + case SHeader if VersionContext.current.isV3OrLaterErgoTreeVersion => val depth = r.level r.level = depth + 1 val res = new CHeader(ErgoHeader.sigmaSerializer.parse(r.asInstanceOf[SigmaByteReader])) diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 5122ee940c..531285909d 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -348,7 +348,7 @@ class ErgoTreeSerializer { val w = SigmaSerializer.startWriter() w.put(header) // header byte - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { // fix in v6.0 to save tree size to respect size bit of the original tree if (ErgoTree.hasSize(header)) { val size = constBytes.length + treeBytes.length diff --git a/interpreter/shared/src/test/scala/sigma/ast/SigmaBuilderTest.scala b/interpreter/shared/src/test/scala/sigma/ast/SigmaBuilderTest.scala index ea3fa5d5ec..ce007d0e7f 100644 --- a/interpreter/shared/src/test/scala/sigma/ast/SigmaBuilderTest.scala +++ b/interpreter/shared/src/test/scala/sigma/ast/SigmaBuilderTest.scala @@ -138,7 +138,7 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma val v = true val c = BooleanConstant(v) test[SBoolean.type](v, c) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { testArray[SBoolean.type](v, c) } else { testArrayFailure[SBoolean.type](v, c) @@ -151,7 +151,7 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma val c = ByteConstant(v) testNumeric[SByte.type](v, c) testLiftingOfCAnyValue[SByte.type](v, c) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { testArray[SByte.type](v, c) } else { testArrayFailure[SByte.type](v, c) @@ -164,7 +164,7 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma val c = ShortConstant(v) testNumeric[SShort.type](v, c) testLiftingOfCAnyValue[SShort.type](v, c) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { testArray[SShort.type](v, c) } else { testArrayFailure[SShort.type](v, c) @@ -176,7 +176,7 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma val v = 1 val c = IntConstant(v) test[SInt.type](v, c) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { testArray[SInt.type](v, c) } else { testArrayFailure[SInt.type](v, c) @@ -188,7 +188,7 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma val v = 1L val c = LongConstant(v) test[SLong.type](v, c) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { testArray[SLong.type](v, c) } else { testArrayFailure[SLong.type](v, c) @@ -199,7 +199,7 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma property("liftToConstant String") { val v = "abc" val c = StringConstant(v) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { // v6.0: String should not be liftable at all (not supported in ErgoTree) (see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/905) test[SString.type](v, c) testArray[SString.type](v, c) @@ -212,13 +212,13 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma property("liftToConstant BigInteger") { val v = BigInteger.valueOf(1L) val c = BigIntConstant(v) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { testSuccess(v, c) } else { testFailure(v) } val arr = Array.fill(10)(v) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { testSuccess(arr, TransformingSigmaBuilder.mkCollectionConstant[SBigInt.type](arr.map(SigmaDsl.BigInt), c.tpe)) } else { testFailure(arr) @@ -244,7 +244,7 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma property("liftToConstant Header") { val h = TestData.h1 val c = HeaderConstant(h) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { testSuccess(h, c) } else { testFailure(h) @@ -256,7 +256,7 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma property("liftToConstant ErgoBox") { val v = TestData.b2.asInstanceOf[CBox].wrappedValue val c = BoxConstant(TestData.b2) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { testSuccess(v, c) } else { testFailure(v) @@ -287,7 +287,7 @@ class SigmaBuilderTest extends AnyPropSpec with ScalaCheckPropertyChecks with Ma property("liftToConstant AvlTreeData") { val v = TestData.t1.asInstanceOf[CAvlTree].wrappedValue val c = AvlTreeConstant(SigmaDsl.avlTree(v)) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { testSuccess(v, c) } else { testFailure(v) diff --git a/interpreter/shared/src/test/scala/sigma/serialization/generators/ObjectGenerators.scala b/interpreter/shared/src/test/scala/sigma/serialization/generators/ObjectGenerators.scala index 1af51d4eee..52bd629e70 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/generators/ObjectGenerators.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/generators/ObjectGenerators.scala @@ -329,7 +329,7 @@ trait ObjectGenerators extends TypeGenerators longConstGen, booleanConstGen, bigIntConstGen, - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { unsignedBigIntConstGen } else { bigIntConstGen diff --git a/interpreter/shared/src/test/scala/sigma/serialization/generators/TypeGenerators.scala b/interpreter/shared/src/test/scala/sigma/serialization/generators/TypeGenerators.scala index c27053ebf2..53bb8de156 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/generators/TypeGenerators.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/generators/TypeGenerators.scala @@ -24,7 +24,7 @@ trait TypeGenerators { Gen.oneOf[SPrimType](SBoolean, SByte, SShort, SInt, SLong, SBigInt, SUnsignedBigInt, SGroupElement, SSigmaProp, SUnit) implicit val arbPrimType: Arbitrary[SPrimType] = Arbitrary(primTypeGen) implicit val predefTypeGen: Gen[SPredefType] = { - if(VersionContext.current.isV6SoftForkActivated){ + if(VersionContext.current.isV3OrLaterErgoTreeVersion){ Gen.oneOf[SPredefType](SBoolean, SByte, SShort, SInt, SLong, SBigInt, SUnsignedBigInt, SGroupElement, SSigmaProp, SUnit, SBox, SAvlTree, SHeader) } else { Gen.oneOf[SPredefType](SBoolean, SByte, SShort, SInt, SLong, SBigInt, SGroupElement, SSigmaProp, SUnit, SBox, SAvlTree) @@ -42,7 +42,7 @@ trait TypeGenerators { intTypeGen, longTypeGen, bigIntTypeGen, - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { unsignedBigIntTypeGen } else { bigIntTypeGen diff --git a/sc/shared/src/main/scala/sigma/compiler/ir/GraphBuilding.scala b/sc/shared/src/main/scala/sigma/compiler/ir/GraphBuilding.scala index f5235aba5e..df968b010c 100644 --- a/sc/shared/src/main/scala/sigma/compiler/ir/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigma/compiler/ir/GraphBuilding.scala @@ -1055,7 +1055,7 @@ trait GraphBuilding extends Base with DefRewriting { IR: IRContext => case (box: Ref[Box]@unchecked, SBoxMethods) => method.name match { case SBoxMethods.tokensMethod.name => box.tokens - case SBoxMethods.getRegMethodV6.name if VersionContext.current.isV6SoftForkActivated => + case SBoxMethods.getRegMethodV6.name if VersionContext.current.isV3OrLaterErgoTreeVersion => val c1 = asRep[Int](argsV(0)) val c2 = stypeToElem(typeSubst.apply(tT)) box.getReg(c1)(c2) @@ -1188,7 +1188,7 @@ trait GraphBuilding extends Base with DefRewriting { IR: IRContext => h.powDistance case SHeaderMethods.votesMethod.name => h.votes - case SHeaderMethods.checkPowMethod.name if VersionContext.current.isV6SoftForkActivated => + case SHeaderMethods.checkPowMethod.name if VersionContext.current.isV3OrLaterErgoTreeVersion => h.checkPow case _ => throwError() } @@ -1199,26 +1199,26 @@ trait GraphBuilding extends Base with DefRewriting { IR: IRContext => val c1 = asRep[Coll[Byte]](argsV(0)) val c2 = asRep[Coll[Byte]](argsV(1)) g.xor(c1, c2) - case SGlobalMethods.encodeNBitsMethod.name if VersionContext.current.isV6SoftForkActivated => + case SGlobalMethods.encodeNBitsMethod.name if VersionContext.current.isV3OrLaterErgoTreeVersion => val c1 = asRep[BigInt](argsV(0)) g.encodeNbits(c1) - case SGlobalMethods.decodeNBitsMethod.name if VersionContext.current.isV6SoftForkActivated => + case SGlobalMethods.decodeNBitsMethod.name if VersionContext.current.isV3OrLaterErgoTreeVersion => val c1 = asRep[Long](argsV(0)) g.decodeNbits(c1) - case SGlobalMethods.powHitMethod.name if VersionContext.current.isV6SoftForkActivated => + case SGlobalMethods.powHitMethod.name if VersionContext.current.isV3OrLaterErgoTreeVersion => val k = asRep[Int](argsV(0)) val msg = asRep[Coll[Byte]](argsV(1)) val nonce = asRep[Coll[Byte]](argsV(2)) val h = asRep[Coll[Byte]](argsV(3)) val N = asRep[Int](argsV(4)) g.powHit(k, msg, nonce, h, N) - case SGlobalMethods.encodeNBitsMethod.name if VersionContext.current.isV6SoftForkActivated => + case SGlobalMethods.encodeNBitsMethod.name if VersionContext.current.isV3OrLaterErgoTreeVersion => val c1 = asRep[BigInt](argsV(0)) g.encodeNbits(c1) - case SGlobalMethods.decodeNBitsMethod.name if VersionContext.current.isV6SoftForkActivated => + case SGlobalMethods.decodeNBitsMethod.name if VersionContext.current.isV3OrLaterErgoTreeVersion => val c1 = asRep[Long](argsV(0)) g.decodeNbits(c1) - case SGlobalMethods.deserializeToMethod.name if VersionContext.current.isV6SoftForkActivated => + case SGlobalMethods.deserializeToMethod.name if VersionContext.current.isV3OrLaterErgoTreeVersion => val c1 = asRep[Coll[Byte]](argsV(0)) val c2 = stypeToElem(method.stype.tRange.withSubstTypes(typeSubst)) g.deserializeTo(c1)(c2) diff --git a/sc/shared/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala b/sc/shared/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala index 4b3aa2eab5..4b9b6e44fd 100644 --- a/sc/shared/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala +++ b/sc/shared/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala @@ -104,7 +104,7 @@ import sigmastate.utils.Helpers.EitherOps // required for Scala 2.11 // We have versioned check here due to fixed collections equality in 6.0.0 // (PairOfColl equal CollOverArray now) // see (https://github.com/ScorexFoundation/sigmastate-interpreter/issues/909) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { val exp = Coll( (Digest32Coll @@ ErgoAlgos.decodeUnsafe(token1).toColl) -> 10000000L, (Digest32Coll @@ ErgoAlgos.decodeUnsafe(token2).toColl) -> 500L diff --git a/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala b/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala index 0bb92f8249..0cb09201d8 100644 --- a/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala +++ b/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala @@ -8060,7 +8060,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => ) ) ) - if(!VersionContext.current.isV6SoftForkActivated) { + if(!VersionContext.current.isV3OrLaterErgoTreeVersion) { verifyCases( // (coll, (index, default)) { @@ -8698,7 +8698,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => "{ (x: Option[Long]) => x.isDefined }", FuncValue(Vector((1, SOption(SLong))), OptionIsDefined(ValUse(1, SOption(SLong)))))) - if (!VersionContext.current.isV6SoftForkActivated) { + if (!VersionContext.current.isV3OrLaterErgoTreeVersion) { verifyCases( Seq( (None -> Expected(Success(1L), 1766, costDetails3, 1766, Seq.fill(4)(2006))), diff --git a/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala b/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala index 29b78d0e97..40caeea819 100644 --- a/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala +++ b/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala @@ -937,7 +937,7 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => property("BigInt - 6.0 features") { import sigma.data.OrderingOps.BigIntOrdering - if (activatedVersionInTests < VersionContext.V6SoftForkVersion) { + if (ergoTreeVersionInTests < VersionContext.V6SoftForkVersion) { // The `Upcast(bigInt, SBigInt)` node is never produced by ErgoScript compiler, but is still valid ErgoTree. // Fixed in 6.0 assertExceptionThrown( @@ -1389,18 +1389,24 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => // for tree v0, the result is the same for all versions (Coll(t1.bytes: _*), 0) -> Expected( Success(Helpers.decodeBytes("100108d27300")), - cost = 1793, + costOpt = None, expectedDetails = CostDetails.ZeroCost, - newCost = 2065, + newCostOpt = None, newVersionedResults = expectedSuccessForAllTreeVersions(Helpers.decodeBytes("100108d27300"), 2065, costDetails(1)) ), // for tree version > 0, the result depend on activated version (Coll(t2.bytes: _*), 0) -> Expected( Success(expectedTreeBytes_beforeV6), - cost = 1793, + costOpt = None, expectedDetails = CostDetails.ZeroCost, - newCost = 2065, - newVersionedResults = expectedSuccessForAllTreeVersions(expectedTreeBytes_V6, 2065, costDetails(1))) + newCostOpt = None, + newVersionedResults = Seq( + 0 -> (ExpectedResult(Success(expectedTreeBytes_beforeV6), Some(2015)) -> Some(costDetails(1))), + 1 -> (ExpectedResult(Success(expectedTreeBytes_beforeV6), Some(2015)) -> Some(costDetails(1))), + 2 -> (ExpectedResult(Success(expectedTreeBytes_beforeV6), Some(2015)) -> Some(costDetails(1))), + 3 -> (ExpectedResult(Success(expectedTreeBytes_V6), Some(2065)) -> Some(costDetails(1))) + ) + ) ), changedFeature( changedInVersion = VersionContext.V6SoftForkVersion, @@ -1868,14 +1874,19 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => Seq( Some(2L) -> Expected(Failure(new java.lang.ArithmeticException("/ by zero")), 6, trace, 1793, newVersionedResults = { - expectedSuccessForAllTreeVersions(2L, 2015, trace) + Seq( + 0 -> (ExpectedResult(Failure(new java.lang.ArithmeticException("/ by zero")), Some(2029)) -> Some(trace)), + 1 -> (ExpectedResult(Failure(new java.lang.ArithmeticException("/ by zero")), Some(2029)) -> Some(trace)), + 2 -> (ExpectedResult(Failure(new java.lang.ArithmeticException("/ by zero")), Some(2029)) -> Some(trace)), + 3 -> (ExpectedResult(Success(2L), Some(2015)) -> Some(trace)) + ) } ), None -> Expected(Failure(new java.lang.ArithmeticException("/ by zero")), 6, trace, 1793) ), changedFeature( changedInVersion = VersionContext.V6SoftForkVersion, { (x: Option[Long]) => val default = 1 / 0L; x.getOrElse(default) }, - { (x: Option[Long]) => if (VersionContext.current.isV6SoftForkActivated) {x.getOrElse(1 / 0L)} else {val default = 1 / 0L; x.getOrElse(default)} }, + { (x: Option[Long]) => if (VersionContext.current.isV3OrLaterErgoTreeVersion) {x.getOrElse(1 / 0L)} else {val default = 1 / 0L; x.getOrElse(default)} }, "{ (x: Option[Long]) => x.getOrElse(1 / 0L) }", FuncValue( Array((1, SOption(SLong))), @@ -1905,7 +1916,7 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => ) def scalaFuncNew(x: Coll[Int]) = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { x.toArray.toIndexedSeq.headOption.getOrElse(1 / 0) } else scalaFuncOld(x) } @@ -1918,7 +1929,12 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => Seq( Coll(1) -> Expected(Failure(new java.lang.ArithmeticException("/ by zero")), 6, trace, 1793, newVersionedResults = { - expectedSuccessForAllTreeVersions(1, 2029, trace) + Seq( + 0 -> (ExpectedResult(Failure(new java.lang.ArithmeticException("/ by zero")), Some(2029)) -> Some(trace)), + 1 -> (ExpectedResult(Failure(new java.lang.ArithmeticException("/ by zero")), Some(2029)) -> Some(trace)), + 2 -> (ExpectedResult(Failure(new java.lang.ArithmeticException("/ by zero")), Some(2029)) -> Some(trace)), + 3 -> (ExpectedResult(Success(1), Some(2029)) -> Some(trace)) + ) } ), Coll[Int]() -> Expected(Failure(new java.lang.ArithmeticException("/ by zero")), 6, trace, 1793) ), @@ -2448,7 +2464,7 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => lazy val bitOr = newFeature[(UnsignedBigInt, UnsignedBigInt), UnsignedBigInt]( { (x: (UnsignedBigInt, UnsignedBigInt)) => (x._1 | x._2) }, "{ (x: (UnsignedBigInt, UnsignedBigInt)) => x._1.bitwiseOr(x._2) }", - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { FuncValue( Array((1, SPair(SUnsignedBigInt, SUnsignedBigInt))), MethodCall.typed[Value[SUnsignedBigInt.type]]( @@ -2483,7 +2499,7 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => lazy val bitNot = newFeature[UnsignedBigInt, UnsignedBigInt]( { (x: UnsignedBigInt) => x.bitwiseInverse() }, "{ (x: UnsignedBigInt) => x.bitwiseInverse }", - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { FuncValue( Array((1, SUnsignedBigInt)), MethodCall.typed[Value[SUnsignedBigInt.type]]( @@ -2849,7 +2865,16 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => lazy val some = newFeature( { (x: Byte) => CSigmaDslBuilder.none[Byte]() }, "{ (x: Byte) => Global.none[Byte]() }", - sinceVersion = V6SoftForkVersion) + FuncValue( + Array((1, SByte)), + MethodCall.typed[Value[SOption[SByte.type]]]( + Global, + SGlobalMethods.noneMethod.withConcreteTypes(Map(STypeVar("T") -> SByte)), + IndexedSeq(), + Map(STypeVar("T") -> SByte) + ) + ), + sinceVersion = V6SoftForkVersion) val cases = Seq( (0.toByte, Success(None)), (1.toByte, Success(None)) diff --git a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala index 7f3f28b791..af9ab986ff 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala @@ -329,7 +329,9 @@ class SigmaDslTesting extends AnyPropSpec val pkAlice = prover.pubKeys.head.toSigmaPropValue val env = Map("pkAlice" -> pkAlice) // Compile script the same way it is performed by applications (i.e. via Ergo Appkit) - val prop = compile(env, code)(IR).asSigmaProp + val prop = VersionContext.withVersions(3, 3) { + compile(env, code)(IR).asSigmaProp + } // Add additional operations which are not yet implemented in ErgoScript compiler val multisig = AtLeast( @@ -404,10 +406,10 @@ class SigmaDslTesting extends AnyPropSpec ctx } - val (expectedResult, expectedCost) = if (activatedVersionInTests < sinceVersion) + val (expectedResult, expectedCost) = if (activatedVersionInTests < sinceVersion || ergoTreeVersionInTests < sinceVersion) (expected.oldResult, expected.verificationCostOpt) else { - val res = expected.newResults(ergoTreeVersionInTests) + val res = expected.newResults(sinceVersion) (res._1, res._1.verificationCost) } @@ -774,7 +776,7 @@ class SigmaDslTesting extends AnyPropSpec checkEq(scalaFuncNew)(newF)(input) } - if (VersionContext.current.activatedVersion < changedInVersion) { + if (VersionContext.current.activatedVersion < changedInVersion && VersionContext.current.ergoTreeVersion < changedInVersion) { // check the old implementation with Scala semantic val expectedOldRes = expected.value @@ -879,7 +881,7 @@ class SigmaDslTesting extends AnyPropSpec extends Feature[A, B] { override def isSupportedIn(vc: VersionContext): Boolean = - vc.activatedVersion >= sinceVersion + vc.activatedVersion >= sinceVersion && vc.ergoTreeVersion >= sinceVersion override def scalaFunc: A => B = { x => if (isSupportedIn(VersionContext.current)) { @@ -1096,6 +1098,21 @@ class SigmaDslTesting extends AnyPropSpec commonNewResults.updateMany(newVersionedResults).toSeq } } + + def apply[A](value: Try[A], + costOpt: Option[Int], + expectedDetails: CostDetails, + newCostOpt: Option[Int], + newVersionedResults: Seq[(Int, (ExpectedResult[A], Option[CostDetails]))]): Expected[A] = + new Expected[A](ExpectedResult(value, costOpt)) { + override val newResults = { + val commonNewResults = defaultNewResults.map { + case (res, _) => + (ExpectedResult(res.value, newCostOpt), Option(expectedDetails)) + } + commonNewResults.updateMany(newVersionedResults).toSeq + } + } } /** Describes existing language feature which should be equally supported in both diff --git a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala index 0504a79c65..ce125c3be8 100644 --- a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala @@ -316,7 +316,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit with C */ case class MInfo(methodId: Byte, method: SMethod, isResolvableFromIds: Boolean = true) - def isV6Activated = VersionContext.current.isV6SoftForkActivated + def isV6Activated = VersionContext.current.isV3OrLaterErgoTreeVersion // NOTE, the type code constants are checked above // The methodId codes as checked here, they MUST be PRESERVED. @@ -476,7 +476,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit with C MInfo(4, MultiplyMethod), MInfo(5, NegateMethod) ) ++ { - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { Seq(MInfo(6, ExponentiateUnsignedMethod)) } else { Seq.empty @@ -550,7 +550,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit with C MInfo(1, dataInputsMethod), MInfo(2, headersMethod), MInfo(3, preHeaderMethod), MInfo(4, inputsMethod), MInfo(5, outputsMethod), MInfo(6, heightMethod), MInfo(7, selfMethod), MInfo(8, selfBoxIndexMethod), MInfo(9, lastBlockUtxoRootHashMethod), - MInfo(10, minerPubKeyMethod)) ++ (if(VersionContext.current.isV6SoftForkActivated){ + MInfo(10, minerPubKeyMethod)) ++ (if(VersionContext.current.isV3OrLaterErgoTreeVersion){ Seq(MInfo(11, getVarV6Method), MInfo(12, getVarFromInputMethod)) } else { Seq(MInfo(11, getVarV5Method)) diff --git a/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index 4075ec5d77..fd2afafc07 100644 --- a/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -267,7 +267,7 @@ class TestingInterpreterSpecification extends CompilerTestingCommons property("BigInt downcasting to byte") { def test() = testEval("{ sigmaProp(0L.toBigInt.toByte <= CONTEXT.preHeader.version) }") - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { test() } else { an[Exception] shouldBe thrownBy(test()) @@ -276,7 +276,7 @@ class TestingInterpreterSpecification extends CompilerTestingCommons property("BigInt downcasting to short") { def test() = testEval("{ sigmaProp(0L.toBigInt.toShort <= CONTEXT.preHeader.version.toShort) }") - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { test() } else { an[Exception] shouldBe thrownBy(test()) @@ -285,7 +285,7 @@ class TestingInterpreterSpecification extends CompilerTestingCommons property("BigInt downcasting to int") { def test() = testEval("{ sigmaProp(1L.toBigInt.toInt < CONTEXT.preHeader.timestamp.toInt) }") - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { test() } else { an[Exception] shouldBe thrownBy(test()) @@ -294,7 +294,7 @@ class TestingInterpreterSpecification extends CompilerTestingCommons property("BigInt downcasting to long") { def test() = testEval("{ sigmaProp(1L.toBigInt.toLong < CONTEXT.preHeader.timestamp) }") - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { test() } else { an[Exception] shouldBe thrownBy(test()) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 2194414ab0..6941be2145 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -127,7 +127,7 @@ class BasicOpsSpecification extends CompilerTestingCommons propExp.asSigmaProp } else { // compile with the latest compiler version, to get validation exception during execution, not compilation error - withVersions(VersionContext.MaxSupportedScriptVersion, ergoTreeVersionInTests) { + withVersions(VersionContext.MaxSupportedScriptVersion, VersionContext.MaxSupportedScriptVersion) { compile(env, script).asBoolValue.toSigmaProp } } @@ -152,7 +152,7 @@ class BasicOpsSpecification extends CompilerTestingCommons val ctx = ErgoLikeContextTesting(currentHeight = 0, lastBlockUtxoRoot = AvlTreeData.dummy, ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(boxToSpend), - spendingTransaction = tx, self = boxToSpend, activatedVersionInTests) + spendingTransaction = tx, self = boxToSpend, ergoTreeVersionInTests) val pr = prover.prove(env + (ScriptNameProp -> s"${name}_prove"), tree, ctx, fakeMessage).getOrThrow @@ -193,7 +193,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { getVarTest() } else { an[sigma.validation.ValidationException] should be thrownBy getVarTest() @@ -214,7 +214,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { getVarTest() } else { an[sigma.validation.ValidationException] should be thrownBy getVarTest() @@ -232,7 +232,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { getVarTest() } else { an[sigma.validation.ValidationException] should be thrownBy getVarTest() @@ -258,8 +258,8 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy deserTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() } @@ -279,8 +279,8 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy conversionTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy conversionTest() } else { conversionTest() } @@ -297,8 +297,8 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy conversionTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy conversionTest() } else { an[Exception] should be thrownBy conversionTest() } @@ -314,7 +314,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[Exception] should be thrownBy conversionTest() } else { an[sigma.exceptions.InvalidArguments] should be thrownBy conversionTest() @@ -334,8 +334,8 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy conversionTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy conversionTest() } else { conversionTest() } @@ -354,8 +354,8 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy conversionTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy conversionTest() } else { conversionTest() } @@ -373,8 +373,8 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy conversionTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.serialization.SerializerException] should be thrownBy conversionTest() } else { conversionTest() } @@ -392,8 +392,8 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy conversionTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.serialization.SerializerException] should be thrownBy conversionTest() } else { an[Exception] should be thrownBy conversionTest() } @@ -410,8 +410,8 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy conversionTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy conversionTest() } else { conversionTest() } @@ -427,7 +427,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[Exception] should be thrownBy conversionTest() } else { val t = Try(conversionTest()) @@ -504,8 +504,8 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy schnorrTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy schnorrTest() } else { schnorrTest() } @@ -525,7 +525,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[Exception] should be thrownBy miTest() } else { miTest() @@ -545,8 +545,8 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy miTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy miTest() } else { miTest() } @@ -565,8 +565,8 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy miTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy miTest() } else { miTest() } @@ -586,8 +586,8 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy miTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy miTest() } else { miTest() } @@ -607,8 +607,8 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy miTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy miTest() } else { miTest() } @@ -628,8 +628,8 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy miTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy miTest() } else { miTest() } @@ -740,8 +740,8 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy rangeTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy rangeTest() } else { rangeTest() } @@ -799,8 +799,8 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { - an[Exception] should be thrownBy circuitTest() + if (ergoTreeVersionInTests < V6SoftForkVersion) { + an[sigma.validation.ValidationException] should be thrownBy circuitTest() } else { circuitTest() } @@ -818,7 +818,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBitsTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(toBitsTest()) @@ -840,7 +840,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBitsTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(toBitsTest()) @@ -857,7 +857,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBitsTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(toBitsTest()) @@ -875,7 +875,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBitsTest() } else { an[ValidationException] shouldBe thrownBy(toBitsTest()) @@ -892,7 +892,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBitsTest() } else { an[ValidationException] shouldBe thrownBy(toBitsTest()) @@ -910,7 +910,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseInverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseInverseTest()) @@ -927,7 +927,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseInverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseInverseTest()) @@ -944,7 +944,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseInverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseInverseTest()) @@ -964,7 +964,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseInverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseInverseTest()) @@ -985,7 +985,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseOrTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseOrTest()) @@ -1001,7 +1001,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseOrTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseOrTest()) @@ -1017,7 +1017,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseOrTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseOrTest()) @@ -1035,7 +1035,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseOrTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseOrTest()) @@ -1052,7 +1052,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseAndTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseAndTest()) @@ -1069,7 +1069,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseAndTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseAndTest()) @@ -1089,7 +1089,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseAndTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseAndTest()) @@ -1109,7 +1109,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseAndTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseAndTest()) @@ -1129,7 +1129,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseXorTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseXorTest()) @@ -1149,7 +1149,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { bitwiseAndTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(bitwiseAndTest()) @@ -1166,7 +1166,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { shiftLeftTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftLeftTest()) @@ -1183,7 +1183,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { an[IllegalArgumentException] shouldBe thrownBy(shiftLeftTest()) } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftLeftTest()) @@ -1200,7 +1200,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { shiftLeftTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftLeftTest()) @@ -1217,7 +1217,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { shiftLeftTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftLeftTest()) @@ -1234,7 +1234,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { shiftLeftTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftLeftTest()) @@ -1250,7 +1250,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { an[ArithmeticException] shouldBe thrownBy(shiftLeftTest()) } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftLeftTest()) @@ -1267,7 +1267,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { an[java.lang.IllegalArgumentException] shouldBe thrownBy(shiftLeftTest()) } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftLeftTest()) @@ -1283,7 +1283,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { an[ArithmeticException] shouldBe thrownBy(shiftLeftTest()) } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftLeftTest()) @@ -1300,7 +1300,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { shiftRightTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftRightTest()) @@ -1317,7 +1317,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { shiftRightTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftRightTest()) @@ -1334,7 +1334,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { an[IllegalArgumentException] shouldBe thrownBy(shiftRightTest()) } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftRightTest()) @@ -1352,7 +1352,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { shiftRightTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftRightTest()) @@ -1369,7 +1369,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { an[IllegalArgumentException] shouldBe thrownBy(shiftRightTest()) } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftRightTest()) @@ -1387,7 +1387,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { shiftRightTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftRightTest()) @@ -1405,7 +1405,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { an[IllegalArgumentException] shouldBe thrownBy(shiftRightTest()) } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftRightTest()) @@ -1423,7 +1423,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { shiftRightTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftRightTest()) @@ -1441,7 +1441,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { an[java.lang.IllegalArgumentException] shouldBe thrownBy(shiftRightTest()) } else { an[sigma.validation.ValidationException] shouldBe thrownBy(shiftRightTest()) @@ -1459,7 +1459,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { getVarTest() } else { an[sigma.validation.ValidationException] should be thrownBy getVarTest() @@ -1480,7 +1480,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { reverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(reverseTest()) @@ -1501,7 +1501,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { reverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(reverseTest()) @@ -1525,7 +1525,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { reverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(reverseTest()) @@ -1549,7 +1549,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { reverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(reverseTest()) @@ -1573,7 +1573,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { reverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(reverseTest()) @@ -1597,7 +1597,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { reverseTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(reverseTest()) @@ -1615,7 +1615,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { getTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(getTest()) @@ -1631,7 +1631,7 @@ class BasicOpsSpecification extends CompilerTestingCommons |""".stripMargin, null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { fromTest() } else { an[sigma.validation.ValidationException] should be thrownBy(fromTest()) @@ -1647,7 +1647,7 @@ class BasicOpsSpecification extends CompilerTestingCommons |""".stripMargin, null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { fromTest() } else { an[sigma.validation.ValidationException] should be thrownBy(fromTest()) @@ -1663,7 +1663,7 @@ class BasicOpsSpecification extends CompilerTestingCommons |""".stripMargin, null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { fromTest() } else { an[sigma.validation.ValidationException] should be thrownBy(fromTest()) @@ -1680,7 +1680,7 @@ class BasicOpsSpecification extends CompilerTestingCommons |""".stripMargin, null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { fromTest() } else { an[sigma.validation.ValidationException] should be thrownBy(fromTest()) @@ -1700,7 +1700,7 @@ class BasicOpsSpecification extends CompilerTestingCommons |""".stripMargin, null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { fromTest() } else { an[sigma.validation.ValidationException] should be thrownBy(fromTest()) @@ -1717,7 +1717,7 @@ class BasicOpsSpecification extends CompilerTestingCommons |""".stripMargin, null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { fromTest() } else { an[sigma.validation.ValidationException] should be thrownBy(fromTest()) @@ -1736,7 +1736,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBytesTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(toBytesTest()) @@ -1755,7 +1755,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBytesTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(toBytesTest()) @@ -1774,7 +1774,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBytesTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(toBytesTest()) @@ -1791,7 +1791,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBytesTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(toBytesTest()) @@ -1806,7 +1806,7 @@ class BasicOpsSpecification extends CompilerTestingCommons def toBytesTest() = test("UnsignedBigInt.toBytes", env, ext, script, null) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBytesTest() } else { an[ValidationException] shouldBe thrownBy(toBytesTest()) @@ -1822,7 +1822,7 @@ class BasicOpsSpecification extends CompilerTestingCommons def toBytesTest() = test("UnsignedBigInt.toBytes", env, ext, script, null) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { toBytesTest() } else { an[ValidationException] shouldBe thrownBy(toBytesTest()) @@ -1839,7 +1839,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -1856,7 +1856,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -1873,7 +1873,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -1892,7 +1892,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -1913,7 +1913,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -1934,7 +1934,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -1957,7 +1957,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -1981,7 +1981,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2003,7 +2003,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[sigma.validation.ValidationException] should be thrownBy deserTest() } else { // we have wrapped CostLimitException here @@ -2023,7 +2023,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { optTest() } else { assertExceptionThrown(optTest(), _.isInstanceOf[NoSuchElementException]) @@ -2041,7 +2041,7 @@ class BasicOpsSpecification extends CompilerTestingCommons null ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { optTest() } else { assertExceptionThrown(optTest(), _.isInstanceOf[NoSuchElementException]) @@ -2088,7 +2088,7 @@ class BasicOpsSpecification extends CompilerTestingCommons testExceededCost = false ) } - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[sigma.validation.ValidationException] should be thrownBy powTest() } else { powTest() @@ -2120,7 +2120,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[sigma.validation.ValidationException] should be thrownBy powTest() } else { powTest() @@ -2140,7 +2140,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[Exception] should be thrownBy deserTest() } else { deserTest() @@ -2157,7 +2157,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true )} - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2177,7 +2177,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2199,7 +2199,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2217,7 +2217,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2244,7 +2244,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2264,7 +2264,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2285,7 +2285,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2305,7 +2305,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2325,7 +2325,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2348,7 +2348,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an [sigma.validation.ValidationException] should be thrownBy deserTest() } else { an [Exception] should be thrownBy deserTest() @@ -2403,7 +2403,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2429,7 +2429,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if (activatedVersionInTests < V6SoftForkVersion) { + if (ergoTreeVersionInTests < V6SoftForkVersion) { an[sigma.validation.ValidationException] should be thrownBy deserTest() } else { deserTest() @@ -2752,7 +2752,7 @@ class BasicOpsSpecification extends CompilerTestingCommons true ) - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV3OrLaterErgoTreeVersion) { holTest() } else { an[sigma.validation.ValidationException] shouldBe thrownBy(holTest()) @@ -3085,7 +3085,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { getRegTest() } else { an[sigma.exceptions.ConstraintFailed] should be thrownBy getRegTest() @@ -3106,7 +3106,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { getRegTest() } else { an[java.nio.BufferUnderflowException] should be thrownBy getRegTest() @@ -3149,7 +3149,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { someTest() } else { an[sigma.validation.ValidationException] should be thrownBy someTest() @@ -3171,7 +3171,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { someTest() } else { an[sigma.validation.ValidationException] should be thrownBy someTest() @@ -3193,7 +3193,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { someTest() } else { an[sigma.validation.ValidationException] should be thrownBy someTest() From 2f557e1ef2c8ce94901accc6edc7ce798d3375b1 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Sat, 14 Dec 2024 00:14:46 +0300 Subject: [PATCH 12/25] back to activated script version for serializers --- .../src/main/scala/sigma/VersionContext.scala | 2 + .../serialization/CoreDataSerializer.scala | 8 +- .../sigma/serialization/DataSerializer.scala | 4 +- .../serialization/ErgoTreeSerializer.scala | 194 +++++++++--------- .../sigmastate/interpreter/Interpreter.scala | 3 +- 5 files changed, 110 insertions(+), 101 deletions(-) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 6c7ffd0720..ef878a3ccf 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -26,6 +26,8 @@ case class VersionContext(activatedVersion: Byte, ergoTreeVersion: Byte) { * including v6.0 update. */ def isV3OrLaterErgoTreeVersion: Boolean = ergoTreeVersion >= V6SoftForkVersion + def isV6Activated: Boolean = activatedVersion >= V6SoftForkVersion + } object VersionContext { diff --git a/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala b/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala index 1f6f95b471..8884fc8ec7 100644 --- a/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala +++ b/core/shared/src/main/scala/sigma/serialization/CoreDataSerializer.scala @@ -34,7 +34,7 @@ class CoreDataSerializer { val data = v.asInstanceOf[BigInt].toBigInteger.toByteArray w.putUShort(data.length) w.putBytes(data) - case SUnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => + case SUnsignedBigInt if VersionContext.current.isV6Activated => val data = BigIntegers.asUnsignedByteArray(v.asInstanceOf[CUnsignedBigInt].wrappedValue) w.putUShort(data.length) w.putBytes(data) @@ -73,7 +73,7 @@ class CoreDataSerializer { i += 1 } - case SOption(elemType) if VersionContext.current.isV3OrLaterErgoTreeVersion => + case SOption(elemType) if VersionContext.current.isV6Activated => val o = v.asInstanceOf[Option[elemType.WrappedType]] w.putOption(o){case (w, v) => serialize(v, elemType, w) @@ -113,7 +113,7 @@ class CoreDataSerializer { } val valueBytes = r.getBytes(size) CBigInt(new BigInteger(valueBytes)) - case SUnsignedBigInt if VersionContext.current.isV3OrLaterErgoTreeVersion => + case SUnsignedBigInt if VersionContext.current.isV6Activated => val size: Short = r.getUShort().toShort if (size > SBigInt.MaxSizeInBytes) { throw SerializerException(s"BigInt value doesn't not fit into ${SBigInt.MaxSizeInBytes} bytes: $size") @@ -135,7 +135,7 @@ class CoreDataSerializer { }.toArray[Any] val coll = Colls.fromArray(arr)(sigma.AnyType) Evaluation.toDslTuple(coll, tuple) - case tOption: SOption[_] if VersionContext.current.isV3OrLaterErgoTreeVersion => + case tOption: SOption[_] if VersionContext.current.isV6Activated => r.getOption[tOption.ElemWrappedType] { deserialize(tOption.elemType, r).asInstanceOf[tOption.ElemWrappedType] } diff --git a/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala b/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala index 4955db5bdc..4046b29a18 100644 --- a/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/DataSerializer.scala @@ -16,7 +16,7 @@ object DataSerializer extends CoreDataSerializer { case SBox => val b = v.asInstanceOf[CBox] ErgoBox.sigmaSerializer.serialize(b.ebox, w.asInstanceOf[SigmaByteWriter]) - case SHeader if VersionContext.current.isV3OrLaterErgoTreeVersion => + case SHeader if VersionContext.current.isV6Activated => val h = v.asInstanceOf[CHeader] ErgoHeader.sigmaSerializer.serialize(h.ergoHeader, w.asInstanceOf[SigmaByteWriter]) case _ => @@ -36,7 +36,7 @@ object DataSerializer extends CoreDataSerializer { val res = CBox(ErgoBox.sigmaSerializer.parse(r.asInstanceOf[SigmaByteReader])) r.level = r.level - 1 res - case SHeader if VersionContext.current.isV3OrLaterErgoTreeVersion => + case SHeader if VersionContext.current.isV6Activated => val depth = r.level r.level = depth + 1 val res = new CHeader(ErgoHeader.sigmaSerializer.parse(r.asInstanceOf[SigmaByteReader])) diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 531285909d..06a54a13cd 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -3,7 +3,7 @@ package sigma.serialization import org.ergoplatform.validation.ValidationRules.{CheckDeserializedScriptIsSigmaProp, CheckHeaderSizeBit} import sigma.ast.{Constant, DeserializationSigmaBuilder, ErgoTree, SType, UnparsedErgoTree} import sigma.ast.syntax.ValueOps -import sigma.ast.ErgoTree.{EmptyConstants, HeaderType} +import sigma.ast.ErgoTree.{EmptyConstants, HeaderType, getVersion} import sigma.util.safeNewArray import debox.cfor import sigma.VersionContext @@ -140,37 +140,41 @@ class ErgoTreeSerializer { val bodyPos = r.position val tree = try { try { // nested try-catch to intercept size limit exceptions and rethrow them as ValidationExceptions - val cs = deserializeConstants(h, r) - val previousConstantStore = r.constantStore - // reader with constant store attached is required (to get tpe for a constant placeholder) - r.constantStore = new ConstantStore(cs) - val wasDeserialize_saved = r.wasDeserialize - r.wasDeserialize = false + val treeVersion = getVersion(h) + VersionContext.withVersions(VersionContext.current.activatedVersion, treeVersion) { + val cs = deserializeConstants(h, r) + val previousConstantStore = r.constantStore + // reader with constant store attached is required (to get tpe for a constant placeholder) + r.constantStore = new ConstantStore(cs) - val wasUsingBlockchainContext_saved = r.wasUsingBlockchainContext - r.wasUsingBlockchainContext = false + val wasDeserialize_saved = r.wasDeserialize + r.wasDeserialize = false - val root = ValueSerializer.deserialize(r) - val hasDeserialize = r.wasDeserialize // == true if there was deserialization node - r.wasDeserialize = wasDeserialize_saved + val wasUsingBlockchainContext_saved = r.wasUsingBlockchainContext + r.wasUsingBlockchainContext = false - val isUsingBlockchainContext = r.wasUsingBlockchainContext // == true if there was a node using the blockchain context - r.wasUsingBlockchainContext = wasUsingBlockchainContext_saved + val root = ValueSerializer.deserialize(r) + val hasDeserialize = r.wasDeserialize // == true if there was deserialization node + r.wasDeserialize = wasDeserialize_saved - if (checkType) { - CheckDeserializedScriptIsSigmaProp(root) - } + val isUsingBlockchainContext = r.wasUsingBlockchainContext // == true if there was a node using the blockchain context + r.wasUsingBlockchainContext = wasUsingBlockchainContext_saved + + if (checkType) { + CheckDeserializedScriptIsSigmaProp(root) + } - r.constantStore = previousConstantStore - // now we know the end position of propositionBytes, read them all at once into array - val treeSize = r.position - startPos - r.position = startPos - val propositionBytes = r.getBytes(treeSize) + r.constantStore = previousConstantStore + // now we know the end position of propositionBytes, read them all at once into array + val treeSize = r.position - startPos + r.position = startPos + val propositionBytes = r.getBytes(treeSize) - new ErgoTree( - h, cs, Right(root.asSigmaProp), - propositionBytes, Some(hasDeserialize), Some(isUsingBlockchainContext)) + new ErgoTree( + h, cs, Right(root.asSigmaProp), + propositionBytes, Some(hasDeserialize), Some(isUsingBlockchainContext)) + } } catch { case e: ReaderPositionLimitExceeded => @@ -309,83 +313,87 @@ class ErgoTreeSerializer { val (header, _, constants, treeBytes) = deserializeHeaderWithTreeBytes(r) val nConstants = constants.length - val resBytes = if (VersionContext.current.isJitActivated) { - // need to measure the serialized size of the new constants - // by serializing them into a separate writer - val constW = SigmaSerializer.startWriter() - - // The following `constants.length` should not be serialized when segregation is off - // in the `header`, because in this case there is no `constants` section in the - // ErgoTree serialization format. Thus, applying this `substituteConstants` for - // non-segregated trees will return non-parsable ErgoTree bytes (when - // `constants.length` is put in `w`). - if (ErgoTree.isConstantSegregation(header)) { - constW.putUInt(constants.length) - } + val treeVersion = ErgoTree.getVersion(header) + + val resBytes = VersionContext.withVersions(VersionContext.current.activatedVersion, treeVersion) { + if (VersionContext.current.isJitActivated) { + // need to measure the serialized size of the new constants + // by serializing them into a separate writer + val constW = SigmaSerializer.startWriter() + + // The following `constants.length` should not be serialized when segregation is off + // in the `header`, because in this case there is no `constants` section in the + // ErgoTree serialization format. Thus, applying this `substituteConstants` for + // non-segregated trees will return non-parsable ErgoTree bytes (when + // `constants.length` is put in `w`). + if (ErgoTree.isConstantSegregation(header)) { + constW.putUInt(constants.length) + } - // The following is optimized O(nConstants + position.length) implementation - if (nConstants > 0) { - val backrefs = getPositionsBackref(positions, nConstants) - cfor(0)(_ < nConstants, _ + 1) { i => - val c = constants(i) - val iPos = backrefs(i) // index to `positions` - if (iPos == -1) { - // no position => no substitution, serialize original constant - constantSerializer.serialize(c, constW) - } else { - require(positions(iPos) == i) // INV: backrefs and positions are mutually inverse - val newConst = newVals(iPos) - require(c.tpe == newConst.tpe, - s"expected new constant to have the same ${c.tpe} tpe, got ${newConst.tpe}") - constantSerializer.serialize(newConst, constW) + // The following is optimized O(nConstants + position.length) implementation + if (nConstants > 0) { + val backrefs = getPositionsBackref(positions, nConstants) + cfor(0)(_ < nConstants, _ + 1) { i => + val c = constants(i) + val iPos = backrefs(i) // index to `positions` + if (iPos == -1) { + // no position => no substitution, serialize original constant + constantSerializer.serialize(c, constW) + } else { + require(positions(iPos) == i) // INV: backrefs and positions are mutually inverse + val newConst = newVals(iPos) + require(c.tpe == newConst.tpe, + s"expected new constant to have the same ${c.tpe} tpe, got ${newConst.tpe}") + constantSerializer.serialize(newConst, constW) + } } } - } - val constBytes = constW.toBytes // nConstants + serialized new constants + val constBytes = constW.toBytes // nConstants + serialized new constants - // start composing the resulting tree bytes - val w = SigmaSerializer.startWriter() - w.put(header) // header byte + // start composing the resulting tree bytes + val w = SigmaSerializer.startWriter() + w.put(header) // header byte - if (VersionContext.current.isV3OrLaterErgoTreeVersion) { - // fix in v6.0 to save tree size to respect size bit of the original tree - if (ErgoTree.hasSize(header)) { - val size = constBytes.length + treeBytes.length - w.putUInt(size) // tree size + if (VersionContext.current.isV3OrLaterErgoTreeVersion) { + // fix in v6.0 to save tree size to respect size bit of the original tree + if (ErgoTree.hasSize(header)) { + val size = constBytes.length + treeBytes.length + w.putUInt(size) // tree size + } } - } - w.putBytes(constBytes) // constants section - w.putBytes(treeBytes) // tree section - w.toBytes - } else { - val w = SigmaSerializer.startWriter() - w.put(header) - - // for v4.x compatibility we save constants.length here (see the above comment to - // understand the consequences) - w.putUInt(constants.length) - - // the following is v4.x O(nConstants * positions.length) inefficient implementation - constants.zipWithIndex.foreach { - case (c, i) if positions.contains(i) => - val newVal = newVals(positions.indexOf(i)) - // we need to get newVal's serialized constant value (see ProveDlogSerializer for example) - val constantStore = new ConstantStore() - val valW = SigmaSerializer.startWriter(Some(constantStore)) - valW.putValue(newVal) - val newConsts = constantStore.getAll - require(newConsts.length == 1) - val newConst = newConsts.head - require(c.tpe == newConst.tpe, s"expected new constant to have the same ${c.tpe} tpe, got ${newConst.tpe}") - constantSerializer.serialize(newConst, w) - case (c, _) => - constantSerializer.serialize(c, w) - } + w.putBytes(constBytes) // constants section + w.putBytes(treeBytes) // tree section + w.toBytes + } else { + val w = SigmaSerializer.startWriter() + w.put(header) + + // for v4.x compatibility we save constants.length here (see the above comment to + // understand the consequences) + w.putUInt(constants.length) + + // the following is v4.x O(nConstants * positions.length) inefficient implementation + constants.zipWithIndex.foreach { + case (c, i) if positions.contains(i) => + val newVal = newVals(positions.indexOf(i)) + // we need to get newVal's serialized constant value (see ProveDlogSerializer for example) + val constantStore = new ConstantStore() + val valW = SigmaSerializer.startWriter(Some(constantStore)) + valW.putValue(newVal) + val newConsts = constantStore.getAll + require(newConsts.length == 1) + val newConst = newConsts.head + require(c.tpe == newConst.tpe, s"expected new constant to have the same ${c.tpe} tpe, got ${newConst.tpe}") + constantSerializer.serialize(newConst, w) + case (c, _) => + constantSerializer.serialize(c, w) + } - w.putBytes(treeBytes) - w.toBytes + w.putBytes(treeBytes) + w.toBytes + } } (resBytes, nConstants) diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala index 88d7be4324..369af2a960 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -248,7 +248,7 @@ trait Interpreter { val context1 = context.withInitCost(currCost).asInstanceOf[CTX] val (propTree, context2) = trySoftForkable[(SigmaPropValue, CTX)](whenSoftFork = (TrueSigmaProp, context1)) { // Before ErgoTree V3 the deserialization cost was not added to the total cost - applyDeserializeContextJITC(if (VersionContext.current.activatedVersion >= VersionContext.V6SoftForkVersion) { + applyDeserializeContextJITC(if (VersionContext.current.isV6Activated) { context1 } else { context @@ -360,7 +360,6 @@ trait Interpreter { case None => // proceed normally } VersionContext.withVersions(context.activatedScriptVersion, ergoTree.version) { - // NOTE, ergoTree.complexity is not acrued to the cost in v5.0 val reduced = fullReduction(ergoTree, context, env) reduced.value match { case TrivialProp.TrueProp => (true, reduced.cost) From 988f42ba0347292b3ed45bea0001da5f0300826b Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Mon, 16 Dec 2024 13:26:11 +0300 Subject: [PATCH 13/25] fixing LSV5 tests --- sc/shared/src/test/scala/sigma/SigmaDslTesting.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala index af9ab986ff..eae097b775 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala @@ -406,9 +406,12 @@ class SigmaDslTesting extends AnyPropSpec ctx } - val (expectedResult, expectedCost) = if (activatedVersionInTests < sinceVersion || ergoTreeVersionInTests < sinceVersion) + val (expectedResult, expectedCost) = if ( + (activatedVersionInTests < VersionContext.V6SoftForkVersion && activatedVersionInTests < sinceVersion) || + (activatedVersionInTests < sinceVersion && ergoTreeVersionInTests < sinceVersion) + ) { (expected.oldResult, expected.verificationCostOpt) - else { + } else { val res = expected.newResults(sinceVersion) (res._1, res._1.verificationCost) } @@ -465,7 +468,8 @@ class SigmaDslTesting extends AnyPropSpec val verificationCost = cost.toIntExact if (expectedCost.isDefined) { assertResult(expectedCost.get, - s"Actual verify() cost $cost != expected ${expectedCost.get} (version: ${VersionContext.current.activatedVersion})")(verificationCost) + s"Actual verify() cost $cost != expected ${expectedCost.get} " + + s"(script version: ${VersionContext.current.activatedVersion}, tree version: ${VersionContext.current.ergoTreeVersion})")(verificationCost) } case Failure(t) => throw t From a14a2578822e9746e70a0c30c8d53d9f46eeca39 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 17 Dec 2024 14:04:54 +0300 Subject: [PATCH 14/25] fixing TestingInterpreterSpecification --- .../scala/sigma/LanguageSpecificationV6.scala | 12 +--------- .../TestingInterpreterSpecification.scala | 24 ++++++++----------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala b/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala index 40caeea819..bb0a9f34de 100644 --- a/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala +++ b/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala @@ -14,27 +14,17 @@ import sigma.ast.syntax.TrueSigmaProp import sigma.ast.{SInt, _} import sigma.data.{AvlTreeData, AvlTreeFlags, CAnyValue, CAvlTree, CBigInt, CBox, CHeader, CSigmaProp, ExactNumeric, ProveDHTuple, RType} import sigma.data.CSigmaDslBuilder -import sigma.data.{AvlTreeData, AvlTreeFlags, CAnyValue, CAvlTree, CBigInt, CBox, CGroupElement, CHeader, CSigmaDslBuilder, CSigmaProp, CUnsignedBigInt, ExactNumeric, PairOfCols, ProveDHTuple, RType} +import sigma.data.{CGroupElement, CUnsignedBigInt} import sigma.crypto.SecP256K1Group -import sigma.data.{CBigInt, CBox, CGroupElement, CHeader, CSigmaDslBuilder, ExactNumeric, RType} -import sigma.data.{CBigInt, CBox, CHeader, CSigmaDslBuilder, ExactNumeric, PairOfCols, RType} import sigma.eval.{CostDetails, SigmaDsl, TracedCost} import sigma.serialization.ValueCodes.OpCode import sigma.util.Extensions.{BooleanOps, IntOps} import sigmastate.eval.{CContext, CPreHeader} -import sigma.util.Extensions.{BooleanOps, IntOps} -import sigma.serialization.ValueCodes.OpCode -import sigma.util.Extensions.{BooleanOps, ByteOps, IntOps, LongOps} -import sigma.util.Extensions.{BooleanOps, IntOps} -import sigma.data.RType -import sigma.serialization.ValueCodes.OpCode -import sigma.util.Extensions.{BooleanOps, ByteOps, IntOps, LongOps} import sigma.pow.Autolykos2PowValidation import sigmastate.exceptions.MethodNotFound import sigmastate.utils.Extensions.ByteOpsForSigma import sigmastate.utils.Helpers import sigma.Extensions.ArrayOps -import sigma.Extensions.{ArrayOps, CollOps} import sigma.crypto.CryptoConstants import sigma.interpreter.{ContextExtension, ProverResult} diff --git a/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index fd2afafc07..64516b55e6 100644 --- a/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -10,13 +10,9 @@ import org.ergoplatform._ import org.scalatest.BeforeAndAfterAll import scorex.util.encode.{Base16, Base58} import sigma.Colls -import sigma.VersionContext.V6SoftForkVersion -import sigma.VersionContext.V6SoftForkVersion -import sigma.VersionContext +import sigma.VersionContext.{V6SoftForkVersion, withVersions} import sigma.data.{CAND, CAvlTree, CBox, CHeader, ProveDlog, SigmaBoolean, TrivialProp} import sigma.interpreter.ContextExtension -import sigma.data.{AvlTreeData, CAND, ProveDlog, SigmaBoolean, TrivialProp} -import sigma.VersionContext.V6SoftForkVersion import sigma.VersionContext import sigma.util.Extensions.IntOps import sigmastate.helpers.{CompilerTestingCommons, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter} @@ -244,10 +240,10 @@ class TestingInterpreterSpecification extends CompilerTestingCommons | Global.encodeNbits(b) == 36626176 |} |""".stripMargin - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigmastate.exceptions.MethodNotFound] should be thrownBy testEval(source) - } else { + if (ergoTreeVersionInTests >= V6SoftForkVersion) { testEval(source) + } else { + an [sigmastate.exceptions.MethodNotFound] should be thrownBy testEval(source) } } @@ -355,10 +351,10 @@ class TestingInterpreterSpecification extends CompilerTestingCommons | Global.powHit(k, msg, nonce, h, N) <= b // hit == b in this example |} |""".stripMargin - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigmastate.exceptions.MethodNotFound] should be thrownBy testEval(source) - } else { + if (ergoTreeVersionInTests >= V6SoftForkVersion) { testEval(source) + } else { + an [sigmastate.exceptions.MethodNotFound] should be thrownBy testEval(source) } } @@ -516,10 +512,10 @@ class TestingInterpreterSpecification extends CompilerTestingCommons | } | """.stripMargin - if (activatedVersionInTests < V6SoftForkVersion) { - an [Exception] should be thrownBy testEval(source) - } else { + if (ergoTreeVersionInTests >= V6SoftForkVersion) { testEval(source) + } else { + an [Exception] should be thrownBy testEval(source) } } From 11a4d3ed31b9f1773d0d5cfc073d3555d22eef84 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 18 Dec 2024 18:01:49 +0300 Subject: [PATCH 15/25] activationType flag for LSV* tests --- .../scala/sigma/LanguageSpecificationV5.scala | 16 +++++++---- .../scala/sigma/LanguageSpecificationV6.scala | 3 +- .../test/scala/sigma/SigmaDslTesting.scala | 28 +++++++++++++++---- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala b/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala index 0cb09201d8..f89ad0b7e6 100644 --- a/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala +++ b/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala @@ -4876,7 +4876,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => Vector(), Map() ) - )), + ), activationType = 0), preGeneratedSamples = Some(samples)) // test vectors to reproduce v4.x bug (see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/603) @@ -5136,6 +5136,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => ) ) ), + activationType = 0, allowNewToSucceed = true ), preGeneratedSamples = Some(ArraySeq.empty)) @@ -6059,7 +6060,9 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => (x: Coll[Boolean]) => SigmaDsl.xorOf(x), (x: Coll[Boolean]) => SigmaDsl.xorOf(x), "{ (x: Coll[Boolean]) => xorOf(x) }", - FuncValue(Vector((1, SBooleanArray)), XorOf(ValUse(1, SBooleanArray))))) + FuncValue(Vector((1, SBooleanArray)), XorOf(ValUse(1, SBooleanArray))), + activationType = 0 + )) } property("LogicalNot equivalence") { @@ -6334,7 +6337,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => (x: (Coll[Byte], Coll[Byte])) => SigmaDsl.xor(x._1, x._2), (x: (Coll[Byte], Coll[Byte])) => SigmaDsl.xor(x._1, x._2), "{ (x: (Coll[Byte], Coll[Byte])) => xor(x._1, x._2) }", - if (lowerMethodCallsInTests) + {if (lowerMethodCallsInTests) FuncValue( Vector((1, STuple(Vector(SByteArray, SByteArray)))), Xor( @@ -6366,7 +6369,8 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => ), Map() ) - ) + )}, + activationType = 0 )) } @@ -8965,6 +8969,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => LongConstant(5L) ) ), + activationType = 0, allowNewToSucceed = true), preGeneratedSamples = Some(Nil)) } @@ -9538,7 +9543,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => ), ConcreteCollection(Array(BoolToSigmaProp(FalseLeaf)), SSigmaProp) ) - ))) + ), activationType = 0)) } // Original issue: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/604 @@ -9687,6 +9692,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => ) ) ), + activationType = 0, allowDifferentErrors = true, allowNewToSucceed = true ), diff --git a/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala b/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala index bb0a9f34de..8d7b5514f0 100644 --- a/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala +++ b/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala @@ -1417,7 +1417,8 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => ), ConcreteCollection(Array(BoolToSigmaProp(FalseLeaf)), SSigmaProp) ) - ) + ), + activationType = 1 ) ) diff --git a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala index eae097b775..1c66163d4d 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala @@ -130,6 +130,9 @@ class SigmaDslTesting extends AnyPropSpec /** Version in which the feature is first implemented of changed. */ def sinceVersion: Byte + /** 0 = script version based activation, 1 = tree version based activation */ + def activationType: Byte + /** Script containing this feature. */ def script: String @@ -407,8 +410,8 @@ class SigmaDslTesting extends AnyPropSpec } val (expectedResult, expectedCost) = if ( - (activatedVersionInTests < VersionContext.V6SoftForkVersion && activatedVersionInTests < sinceVersion) || - (activatedVersionInTests < sinceVersion && ergoTreeVersionInTests < sinceVersion) + (activationType == 0 && activatedVersionInTests < sinceVersion) || + (activationType == 1 && ergoTreeVersionInTests < sinceVersion) ) { (expected.oldResult, expected.verificationCostOpt) } else { @@ -519,6 +522,8 @@ class SigmaDslTesting extends AnyPropSpec override def sinceVersion: Byte = 0 + override val activationType = 0 + override def isSupportedIn(vc: VersionContext): Boolean = true /** in v5.x the old and the new interpreters are the same */ @@ -687,6 +692,7 @@ class SigmaDslTesting extends AnyPropSpec printExpectedExpr: Boolean = true, logScript: Boolean = LogScriptDefault, allowNewToSucceed: Boolean = false, + override val activationType: Byte = 1, override val allowDifferentErrors: Boolean = false )(implicit IR: IRContext, override val evalSettings: EvalSettings, val tA: RType[A], val tB: RType[B]) extends Feature[A, B] { feature => @@ -777,10 +783,16 @@ class SigmaDslTesting extends AnyPropSpec override def checkExpected(input: A, expected: Expected[B]): Unit = { // check the new implementation with Scala semantic function val newRes = VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { - checkEq(scalaFuncNew)(newF)(input) + checkEq(scalaFuncNew)(newF)(input) + } + + val checkOld = if(changedInVersion < V6SoftForkVersion) { + VersionContext.current.activatedVersion < changedInVersion + } else { + VersionContext.current.ergoTreeVersion < changedInVersion } - if (VersionContext.current.activatedVersion < changedInVersion && VersionContext.current.ergoTreeVersion < changedInVersion) { + if (checkOld) { // check the old implementation with Scala semantic val expectedOldRes = expected.value @@ -880,6 +892,7 @@ class SigmaDslTesting extends AnyPropSpec override val scalaFuncNew: A => B, expectedExpr: Option[SValue], printExpectedExpr: Boolean = true, + override val activationType: Byte = 1, logScript: Boolean = LogScriptDefault )(implicit IR: IRContext, override val evalSettings: EvalSettings, val tA: RType[A], val tB: RType[B]) extends Feature[A, B] { @@ -1155,12 +1168,15 @@ class SigmaDslTesting extends AnyPropSpec script: String, expectedExpr: SValue = null, allowNewToSucceed: Boolean = false, - allowDifferentErrors: Boolean = false + allowDifferentErrors: Boolean = false, + activationType: Byte = 1 ) (implicit IR: IRContext, evalSettings: EvalSettings): Feature[A, B] = { ChangedFeature(changedInVersion, script, scalaFunc, scalaFuncNew, Option(expectedExpr), allowNewToSucceed = allowNewToSucceed, - allowDifferentErrors = allowDifferentErrors) + allowDifferentErrors = allowDifferentErrors, + activationType = activationType + ) } /** Describes a NEW language feature which must NOT be supported in v4 and From 592a68cfc44fb76a22056e26c2ca85af83b9f58f Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 18 Dec 2024 23:51:33 +0300 Subject: [PATCH 16/25] fixing LSV6 tests --- .../scala/sigma/serialization/ErgoTreeSerializer.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 06a54a13cd..6aeef35356 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -142,7 +142,8 @@ class ErgoTreeSerializer { try { // nested try-catch to intercept size limit exceptions and rethrow them as ValidationExceptions val treeVersion = getVersion(h) - VersionContext.withVersions(VersionContext.current.activatedVersion, treeVersion) { + val scriptVersion = Math.max(VersionContext.current.activatedVersion, treeVersion).toByte + VersionContext.withVersions(scriptVersion, treeVersion) { val cs = deserializeConstants(h, r) val previousConstantStore = r.constantStore // reader with constant store attached is required (to get tpe for a constant placeholder) @@ -313,9 +314,7 @@ class ErgoTreeSerializer { val (header, _, constants, treeBytes) = deserializeHeaderWithTreeBytes(r) val nConstants = constants.length - val treeVersion = ErgoTree.getVersion(header) - - val resBytes = VersionContext.withVersions(VersionContext.current.activatedVersion, treeVersion) { + val resBytes = { if (VersionContext.current.isJitActivated) { // need to measure the serialized size of the new constants // by serializing them into a separate writer From e9f24c0d57cbf9631192f3a6a449f3376b3ccdc7 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 19 Dec 2024 14:18:35 +0300 Subject: [PATCH 17/25] MethodCallSerializerSpecification fix --- .../MethodCallSerializerSpecification.scala | 68 ++++++++++++++----- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala index 4bfe3c6a25..891d22a78a 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala @@ -38,7 +38,7 @@ class MethodCallSerializerSpecification extends SerializationSpecification { roundTripTest(expr) } - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withVersions(VersionContext.V6SoftForkVersion, VersionContext.V6SoftForkVersion) { code } @@ -47,6 +47,12 @@ class MethodCallSerializerSpecification extends SerializationSpecification { code } ) + + a[ValidationException] should be thrownBy ( + VersionContext.withVersions(VersionContext.V6SoftForkVersion, (VersionContext.V6SoftForkVersion - 1).toByte) { + code + } + ) } property("MethodCall deserialization round trip for Global.powHit") { @@ -65,15 +71,21 @@ class MethodCallSerializerSpecification extends SerializationSpecification { roundTripTest(expr) } - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withVersions(VersionContext.V6SoftForkVersion, VersionContext.V6SoftForkVersion) { code } - an[ValidationException] should be thrownBy ( + a[ValidationException] should be thrownBy ( VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { code } ) + + a[ValidationException] should be thrownBy ( + VersionContext.withVersions(VersionContext.V6SoftForkVersion, (VersionContext.V6SoftForkVersion - 1).toByte) { + code + } + ) } property("MethodCall deserialization round trip for Global.serialize") { @@ -87,15 +99,21 @@ class MethodCallSerializerSpecification extends SerializationSpecification { roundTripTest(expr) } - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withVersions(VersionContext.V6SoftForkVersion, VersionContext.V6SoftForkVersion) { code } - an[ValidationException] should be thrownBy ( + a[ValidationException] should be thrownBy ( VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { code } - ) + ) + + a[ValidationException] should be thrownBy ( + VersionContext.withVersions(VersionContext.V6SoftForkVersion, (VersionContext.V6SoftForkVersion - 1).toByte) { + code + } + ) } property("MethodCall deserialization round trip for Global.deserializeTo[]") { @@ -109,16 +127,21 @@ class MethodCallSerializerSpecification extends SerializationSpecification { roundTripTest(expr) } - println(SGlobalMethods.deserializeToMethod.hasExplicitTypeArgs) - - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withVersions(VersionContext.V6SoftForkVersion, VersionContext.V6SoftForkVersion) { code } - an[Exception] should be thrownBy ( + a[SerializerException] should be thrownBy ( VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { code - }) + } + ) + + a[ValidationException] should be thrownBy ( + VersionContext.withVersions(VersionContext.V6SoftForkVersion, (VersionContext.V6SoftForkVersion - 1).toByte) { + code + } + ) } property("MethodCall deserialization round trip for Global.encodeNBits") { @@ -133,14 +156,21 @@ class MethodCallSerializerSpecification extends SerializationSpecification { } // should be ok - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withVersions(VersionContext.V6SoftForkVersion, VersionContext.V6SoftForkVersion) { code } - an[ValidationException] should be thrownBy ( + a[ValidationException] should be thrownBy ( VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { code - }) + } + ) + + a[ValidationException] should be thrownBy ( + VersionContext.withVersions(VersionContext.V6SoftForkVersion, (VersionContext.V6SoftForkVersion - 1).toByte) { + code + } + ) } property("MethodCall deserialization round trip for Global.decodeNBits") { @@ -154,14 +184,20 @@ class MethodCallSerializerSpecification extends SerializationSpecification { roundTripTest(expr) } - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + VersionContext.withVersions(VersionContext.V6SoftForkVersion, VersionContext.V6SoftForkVersion) { code } - an[ValidationException] should be thrownBy ( + a[ValidationException] should be thrownBy ( VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { code } ) + + a[ValidationException] should be thrownBy ( + VersionContext.withVersions(VersionContext.V6SoftForkVersion, (VersionContext.V6SoftForkVersion - 1).toByte) { + code + } + ) } } From d8839f96f2820a8195447c0e266799104dbdc7bf Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 19 Dec 2024 15:09:52 +0300 Subject: [PATCH 18/25] activation type constants --- .../scala/sigma/LanguageSpecificationV5.scala | 14 +++++++------- .../scala/sigma/LanguageSpecificationV6.scala | 2 +- .../src/test/scala/sigma/SigmaDslTesting.scala | 16 ++++++++++------ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala b/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala index f89ad0b7e6..47f174fa2f 100644 --- a/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala +++ b/sc/shared/src/test/scala/sigma/LanguageSpecificationV5.scala @@ -4876,7 +4876,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => Vector(), Map() ) - ), activationType = 0), + ), activationType = ActivationByScriptVersion), preGeneratedSamples = Some(samples)) // test vectors to reproduce v4.x bug (see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/603) @@ -5136,7 +5136,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => ) ) ), - activationType = 0, + activationType = ActivationByScriptVersion, allowNewToSucceed = true ), preGeneratedSamples = Some(ArraySeq.empty)) @@ -6061,7 +6061,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => (x: Coll[Boolean]) => SigmaDsl.xorOf(x), "{ (x: Coll[Boolean]) => xorOf(x) }", FuncValue(Vector((1, SBooleanArray)), XorOf(ValUse(1, SBooleanArray))), - activationType = 0 + activationType = ActivationByScriptVersion )) } @@ -6370,7 +6370,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => Map() ) )}, - activationType = 0 + activationType = ActivationByScriptVersion )) } @@ -8969,7 +8969,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => LongConstant(5L) ) ), - activationType = 0, + activationType = ActivationByScriptVersion, allowNewToSucceed = true), preGeneratedSamples = Some(Nil)) } @@ -9543,7 +9543,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => ), ConcreteCollection(Array(BoolToSigmaProp(FalseLeaf)), SSigmaProp) ) - ), activationType = 0)) + ), activationType = ActivationByScriptVersion)) } // Original issue: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/604 @@ -9692,7 +9692,7 @@ class LanguageSpecificationV5 extends LanguageSpecificationBase { suite => ) ) ), - activationType = 0, + activationType = ActivationByScriptVersion, allowDifferentErrors = true, allowNewToSucceed = true ), diff --git a/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala b/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala index 8d7b5514f0..4ac743e7ca 100644 --- a/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala +++ b/sc/shared/src/test/scala/sigma/LanguageSpecificationV6.scala @@ -1418,7 +1418,7 @@ class LanguageSpecificationV6 extends LanguageSpecificationBase { suite => ConcreteCollection(Array(BoolToSigmaProp(FalseLeaf)), SSigmaProp) ) ), - activationType = 1 + activationType = ActivationByTreeVersion ) ) diff --git a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala index 1c66163d4d..90e104defe 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala @@ -50,8 +50,12 @@ class SigmaDslTesting extends AnyPropSpec with Matchers with SigmaTestingData with SigmaContractSyntax with CompilerTestingCommons with ObjectGenerators { suite => + override def Coll[T](items: T*)(implicit cT: RType[T]): Coll[T] = super.Coll(items:_*) + protected val ActivationByScriptVersion: Byte = 0.toByte + protected val ActivationByTreeVersion: Byte = 1.toByte + lazy val spec: ContractSpec = TestContractSpec(suite)(new TestingIRContext) override def contractEnv: ScriptEnv = Map() @@ -410,8 +414,8 @@ class SigmaDslTesting extends AnyPropSpec } val (expectedResult, expectedCost) = if ( - (activationType == 0 && activatedVersionInTests < sinceVersion) || - (activationType == 1 && ergoTreeVersionInTests < sinceVersion) + (activationType == ActivationByScriptVersion && activatedVersionInTests < sinceVersion) || + (activationType == ActivationByTreeVersion && ergoTreeVersionInTests < sinceVersion) ) { (expected.oldResult, expected.verificationCostOpt) } else { @@ -522,7 +526,7 @@ class SigmaDslTesting extends AnyPropSpec override def sinceVersion: Byte = 0 - override val activationType = 0 + override val activationType = ActivationByScriptVersion override def isSupportedIn(vc: VersionContext): Boolean = true @@ -692,7 +696,7 @@ class SigmaDslTesting extends AnyPropSpec printExpectedExpr: Boolean = true, logScript: Boolean = LogScriptDefault, allowNewToSucceed: Boolean = false, - override val activationType: Byte = 1, + override val activationType: Byte = ActivationByTreeVersion, override val allowDifferentErrors: Boolean = false )(implicit IR: IRContext, override val evalSettings: EvalSettings, val tA: RType[A], val tB: RType[B]) extends Feature[A, B] { feature => @@ -892,7 +896,7 @@ class SigmaDslTesting extends AnyPropSpec override val scalaFuncNew: A => B, expectedExpr: Option[SValue], printExpectedExpr: Boolean = true, - override val activationType: Byte = 1, + override val activationType: Byte = ActivationByTreeVersion, logScript: Boolean = LogScriptDefault )(implicit IR: IRContext, override val evalSettings: EvalSettings, val tA: RType[A], val tB: RType[B]) extends Feature[A, B] { @@ -1169,7 +1173,7 @@ class SigmaDslTesting extends AnyPropSpec expectedExpr: SValue = null, allowNewToSucceed: Boolean = false, allowDifferentErrors: Boolean = false, - activationType: Byte = 1 + activationType: Byte = ActivationByTreeVersion ) (implicit IR: IRContext, evalSettings: EvalSettings): Feature[A, B] = { ChangedFeature(changedInVersion, script, scalaFunc, scalaFuncNew, Option(expectedExpr), From f59f704e1ea984073547a71f051a5e627cc1eec3 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 20 Dec 2024 19:03:29 +0300 Subject: [PATCH 19/25] fromBlockVersion --- core/shared/src/main/scala/sigma/VersionContext.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index ef878a3ccf..3ff001da56 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -107,4 +107,6 @@ object VersionContext { } } + def fromBlockVersion(blockVersion: Byte): VersionContext = VersionContext((blockVersion - 1).toByte) + } From 905448bdee55de217a604ebb6876878fce3717d1 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 20 Dec 2024 19:10:38 +0300 Subject: [PATCH 20/25] fromBlockVersion fix --- core/shared/src/main/scala/sigma/VersionContext.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 3ff001da56..9efb5911e7 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -107,6 +107,8 @@ object VersionContext { } } - def fromBlockVersion(blockVersion: Byte): VersionContext = VersionContext((blockVersion - 1).toByte) + def fromBlockVersion(blockVersion: Byte): VersionContext = { + VersionContext((blockVersion - 1).toByte, (blockVersion - 1).toByte) + } } From 91b3b985b1c08b0a8f08b40c4ecaa59e332ae9c0 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Mon, 23 Dec 2024 12:15:19 +0300 Subject: [PATCH 21/25] versioning in serializeErgoTree --- .../serialization/ErgoTreeSerializer.scala | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 6aeef35356..5812132e0e 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -103,20 +103,24 @@ class ErgoTreeSerializer { * Doesn't apply any transformations and guarantee to preserve original * structure after deserialization. */ def serializeErgoTree(ergoTree: ErgoTree): Array[Byte] = { - val res = ergoTree.root match { - case Left(UnparsedErgoTree(bytes, _)) => bytes.array.asInstanceOf[Array[Byte]] - case _ => - val bytes = serializeWithoutSize(ergoTree) - if (ergoTree.hasSize) { - val w = SigmaSerializer.startWriter() - val header = bytes(0) - val contentLength = bytes.length - 1 - w.put(header) - w.putUInt(contentLength) - w.putBytes(bytes, 1, contentLength) - w.toBytes - } - else bytes + val treeVersion = ergoTree.version + val scriptVersion = Math.max(VersionContext.current.activatedVersion, treeVersion).toByte + val res = VersionContext.withVersions(scriptVersion, treeVersion) { + ergoTree.root match { + case Left(UnparsedErgoTree(bytes, _)) => bytes.array.asInstanceOf[Array[Byte]] + case _ => + val bytes = serializeWithoutSize(ergoTree) + if (ergoTree.hasSize) { + val w = SigmaSerializer.startWriter() + val header = bytes(0) + val contentLength = bytes.length - 1 + w.put(header) + w.putUInt(contentLength) + w.putBytes(bytes, 1, contentLength) + w.toBytes + } + else bytes + } } res } From ce205f47fb3e5d79fdad69fb54d45638decc462d Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 26 Dec 2024 14:13:54 +0300 Subject: [PATCH 22/25] post-merge fix --- .../scala/sigma/serialization/TypeSerializer.scala | 4 ++-- .../main/scala/sigma/validation/RuleStatus.scala | 2 +- .../scala/sigma/validation/ValidationRules.scala | 2 +- .../ergoplatform/validation/ValidationRules.scala | 14 ++++++++------ data/shared/src/main/scala/sigma/ast/methods.scala | 2 +- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala b/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala index 56a3120cfb..51f4c834af 100644 --- a/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala +++ b/core/shared/src/main/scala/sigma/serialization/TypeSerializer.scala @@ -15,7 +15,7 @@ class TypeSerializer { def getEmbeddableType(code: Int): SType = { // todo : add unsigned bit int to embeddable id to type - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV6Activated) { CheckPrimitiveTypeCodeV6(code.toByte) } else { CheckPrimitiveTypeCode(code.toByte) @@ -222,7 +222,7 @@ class TypeSerializer { case _ => // the #1008 check replaced with one with identical behavior but different opcode (1018), to activate // ReplacedRule(1008 -> 1018) during 6.0 activation - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV6Activated) { CheckTypeCodeV6(c.toByte) } else { CheckTypeCode(c.toByte) diff --git a/core/shared/src/main/scala/sigma/validation/RuleStatus.scala b/core/shared/src/main/scala/sigma/validation/RuleStatus.scala index 3d0451b240..ae1a380898 100644 --- a/core/shared/src/main/scala/sigma/validation/RuleStatus.scala +++ b/core/shared/src/main/scala/sigma/validation/RuleStatus.scala @@ -32,7 +32,7 @@ case object DisabledRule extends RuleStatus { * @see `ValidationSettings.isSoftFork` * @param newRuleId id of a new rule which replaces the rule marked with this status */ -case class ReplacedRule(newRuleId: Short) extends RuleStatus { +case class ReplacedRule(newRuleId: Short) extends RuleStatus { val statusCode: Byte = RuleStatus.ReplacedRuleCode } diff --git a/core/shared/src/main/scala/sigma/validation/ValidationRules.scala b/core/shared/src/main/scala/sigma/validation/ValidationRules.scala index 6321ae6ba6..3cae0a3f27 100644 --- a/core/shared/src/main/scala/sigma/validation/ValidationRules.scala +++ b/core/shared/src/main/scala/sigma/validation/ValidationRules.scala @@ -208,7 +208,7 @@ object ValidationRules { ) private def ruleSpecs: Seq[ValidationRule] = { - if(VersionContext.current.isV6SoftForkActivated) { + if(VersionContext.current.isV6Activated) { ruleSpecsV6 } else { ruleSpecsV5 diff --git a/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index 4c75de6623..5ad09b7733 100644 --- a/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -120,11 +120,13 @@ object ValidationRules { override def isSoftFork(vs: SigmaValidationSettings, ruleId: Short, status: RuleStatus, - args: Seq[Any]): Boolean = (status, args) match { - case (ChangedRule(newValue), Seq(objType: MethodsContainer, methodId: Byte)) => - val key = Array(objType.ownerType.typeId, methodId) - newValue.grouped(2).exists(java.util.Arrays.equals(_, key)) - case _ => false + args: Seq[Any]): Boolean = { + (status, args) match { + case (ChangedRule(newValue), Seq(objType: MethodsContainer, methodId: Byte)) => + val key = Array(objType.ownerType.typeId, methodId) + newValue.grouped(2).exists(java.util.Arrays.equals(_, key)) + case _ => false + } } } @@ -183,7 +185,7 @@ object ValidationRules { } def ruleSpecs: Seq[ValidationRule] = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV6Activated) { ruleSpecsV6 } else { ruleSpecsV5 diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index 4ba5208705..e40ec30e7c 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -91,7 +91,7 @@ sealed trait MethodsContainer { * @see getMethodById */ def methodById(methodId: Byte): SMethod = { - if (VersionContext.current.isV6SoftForkActivated) { + if (VersionContext.current.isV6Activated) { ValidationRules.CheckAndGetMethodV6(this, methodId) } else { ValidationRules.CheckAndGetMethod(this, methodId) From f6b801fa54fda7702b508bf40b0dbd70a586c00a Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 26 Dec 2024 15:14:07 +0300 Subject: [PATCH 23/25] replacedrule fix --- .../validation/SigmaValidationSettings.scala | 8 +++++++- .../ergoplatform/validation/ValidationRules.scala | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/core/shared/src/main/scala/sigma/validation/SigmaValidationSettings.scala b/core/shared/src/main/scala/sigma/validation/SigmaValidationSettings.scala index 51fb97c8ad..70f3c33845 100644 --- a/core/shared/src/main/scala/sigma/validation/SigmaValidationSettings.scala +++ b/core/shared/src/main/scala/sigma/validation/SigmaValidationSettings.scala @@ -1,5 +1,7 @@ package sigma.validation +import sigma.VersionContext + /** * Configuration of validation. Each `ValidationRule` instance should be * implemented as an `object` to facilitate type-safe usage. It then should be @@ -48,7 +50,11 @@ abstract class SigmaValidationSettings extends Iterable[(Short, (ValidationRule, def isSoftFork(ruleId: Short, ve: ValidationException): Boolean = { val infoOpt = get(ruleId) infoOpt match { - case Some((_, ReplacedRule(_))) => true + case Some((vr, ReplacedRule(_))) => if (vr.id == 1011 && VersionContext.current.isV6Activated) { + false + } else { + true + } case Some((rule, status)) => rule.isSoftFork(this, rule.id, status, ve.args) case None => false } diff --git a/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index 5ad09b7733..ed461aa2f2 100644 --- a/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/data/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -109,8 +109,9 @@ object ValidationRules { final def apply[T](objType: MethodsContainer, methodId: Byte): SMethod = { checkRule() val methodOpt = objType.getMethodById(methodId) - if (methodOpt.isDefined) methodOpt.get - else { + if (methodOpt.isDefined) { + methodOpt.get + } else { throwValidationException( new SerializerException(s"The method with code $methodId doesn't declared in the type $objType."), Array[Any](objType, methodId)) @@ -130,7 +131,15 @@ object ValidationRules { } } - object CheckAndGetMethod extends CheckAndGetMethodTemplate(1011) + object CheckAndGetMethod extends CheckAndGetMethodTemplate(1011) { + override def isSoftFork(vs: SigmaValidationSettings, + ruleId: Short, + status: RuleStatus, + args: Seq[Any]): Boolean = { + false + } + } + object CheckAndGetMethodV6 extends CheckAndGetMethodTemplate(1016) object CheckHeaderSizeBit extends ValidationRule(1012, From 15a30964fbcfaf62ff90d1751aa0fc27e531450c Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 26 Dec 2024 16:16:04 +0300 Subject: [PATCH 24/25] full replacedrule id check --- .../main/scala/sigma/validation/SigmaValidationSettings.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/shared/src/main/scala/sigma/validation/SigmaValidationSettings.scala b/core/shared/src/main/scala/sigma/validation/SigmaValidationSettings.scala index 70f3c33845..9063f88bfb 100644 --- a/core/shared/src/main/scala/sigma/validation/SigmaValidationSettings.scala +++ b/core/shared/src/main/scala/sigma/validation/SigmaValidationSettings.scala @@ -50,7 +50,7 @@ abstract class SigmaValidationSettings extends Iterable[(Short, (ValidationRule, def isSoftFork(ruleId: Short, ve: ValidationException): Boolean = { val infoOpt = get(ruleId) infoOpt match { - case Some((vr, ReplacedRule(_))) => if (vr.id == 1011 && VersionContext.current.isV6Activated) { + case Some((vr, ReplacedRule(_))) => if ((vr.id == 1011 || vr.id == 1007 || vr.id == 1008) && VersionContext.current.isV6Activated) { false } else { true From 8aa800214c8d1efdbe6b01516e8c7ed68eeef770 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 10 Jan 2025 18:12:22 +0300 Subject: [PATCH 25/25] fix checkmethod rule test --- .../SoftForkabilitySpecification.scala | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index bce875fd14..1dfd3a3091 100644 --- a/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -3,7 +3,7 @@ package sigmastate import org.ergoplatform._ import org.ergoplatform.validation.ValidationRules._ import org.scalatest.BeforeAndAfterAll -import sigma.{Colls, SigmaTestingData} +import sigma.{Colls, SigmaTestingData, VersionContext} import sigma.ast._ import sigma.ast.SPrimType.MaxPrimTypeCode import sigma.ast.TypeCodes.LastConstantCode @@ -340,12 +340,14 @@ class SoftForkabilitySpecification extends SigmaTestingData } property("CheckMethod rule") { - val freeMethodId = 16.toByte - val mcBytes = Array[Byte](OpCodes.PropertyCallCode, SCollection.typeId, freeMethodId, Outputs.opCode) - val v2vs = vs.updated(CheckAndGetMethod.id, ChangedRule(Array(SCollection.typeId, freeMethodId))) - checkRule(CheckAndGetMethod, v2vs, { - ValueSerializer.deserialize(mcBytes) - }) + VersionContext.withVersions(3,0) { + val freeMethodId = 16.toByte + val mcBytes = Array[Byte](OpCodes.PropertyCallCode, SCollection.typeId, freeMethodId, Outputs.opCode) + val v2vs = vs.updated(CheckAndGetMethodV6.id, ChangedRule(Array(SCollection.typeId, freeMethodId))) + checkRule(CheckAndGetMethodV6, v2vs, { + ValueSerializer.deserialize(mcBytes) + }) + } } override protected def afterAll(): Unit = {