From 6241e86923a252d918d68495128d542f80e2b682 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Mon, 6 Nov 2023 14:39:38 +0300 Subject: [PATCH 01/25] 6.0.0 version set in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 64f08f0277..6b8429a82f 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ This library is on Maven repository and can be added to the SBT configuration of Scala project. ```scala -libraryDependencies += "org.scorexfoundation" %% "sigma-state" % "5.0.6" +libraryDependencies += "org.scorexfoundation" %% "sigma-state" % "6.0.0" ``` ## Repository Organization From 727ed8d655d8c3af5b7ec11cc6208691446cf037 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 22 Nov 2023 14:07:46 +0300 Subject: [PATCH 02/25] evolution version --- 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 14e6dc8b21..18a1d8bccb 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -40,6 +40,8 @@ object VersionContext { */ val JitActivationVersion: Byte = 2 + val ExtensionVersion: Byte = 3 + private val _defaultContext = VersionContext( activatedVersion = 1/* v4.x */, ergoTreeVersion = 1 From 048add38745767a49978b55015dd6daf62e7fdff Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 22 Nov 2023 14:11:34 +0300 Subject: [PATCH 03/25] comments fixed --- core/shared/src/main/scala/sigma/VersionContext.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 18a1d8bccb..4f1903a86c 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -31,6 +31,7 @@ object VersionContext { * - version 3.x this value must be 0 * - in v4.0 must be 1 * - in v5.x must be 2 + * - in 6.x must be 3 * etc. */ val MaxSupportedScriptVersion: Byte = 2 // supported versions 0, 1, 2 @@ -40,7 +41,10 @@ object VersionContext { */ val JitActivationVersion: Byte = 2 - val ExtensionVersion: Byte = 3 + /** + * The version of ErgoTree corresponding to "evolution" (6.0) soft-fork + */ + val EvolutionVersion: Byte = 3 private val _defaultContext = VersionContext( activatedVersion = 1/* v4.x */, From f9856794239258a0137755c3e3ff9e1e35ccbb09 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 2 Apr 2024 21:15:59 +0300 Subject: [PATCH 04/25] versioned tests --- .../shared/src/main/scala/sigma/VersionContext.scala | 12 +++++++++--- .../shared/src/test/scala/sigma/VersionTesting.scala | 11 +++++------ .../scala/sigmastate/ErgoTreeSpecification.scala | 1 + 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 8d3caf4284..b3b53e9f34 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -1,6 +1,6 @@ package sigma -import VersionContext.JitActivationVersion +import VersionContext.{EvolutionVersion, JitActivationVersion} import scala.util.DynamicVariable @@ -21,6 +21,10 @@ case class VersionContext(activatedVersion: Byte, ergoTreeVersion: Byte) { /** @return true, if the activated script version of Ergo protocol on the network is * greater than v1. */ def isJitActivated: Boolean = activatedVersion >= JitActivationVersion + + /** @return true, if the activated script version of Ergo protocol on the network is + * including Evolution update. */ + def isEvolutionActivated: Boolean = activatedVersion >= EvolutionVersion } object VersionContext { @@ -34,9 +38,11 @@ object VersionContext { * - in 6.x must be 3 * etc. */ - val MaxSupportedScriptVersion: Byte = 2 // supported versions 0, 1, 2 + val MaxSupportedScriptVersion: Byte = 3 // supported versions 0, 1, 2, 3 - /** The first version of ErgoTree starting from which the JIT costing interpreter is used. */ + /** The first version of ErgoTree starting from which the JIT costing interpreter must be used. + * It must also be used for all subsequent versions (3, 4, etc). + */ val JitActivationVersion: Byte = 2 /** diff --git a/core/shared/src/test/scala/sigma/VersionTesting.scala b/core/shared/src/test/scala/sigma/VersionTesting.scala index a17fc7a7f9..69e15ff491 100644 --- a/core/shared/src/test/scala/sigma/VersionTesting.scala +++ b/core/shared/src/test/scala/sigma/VersionTesting.scala @@ -6,13 +6,11 @@ import scala.util.DynamicVariable trait VersionTesting { - /** In v5.x we run test for only one activated version on the network (== 2). - * In the branch for v6.0 the new version 3 should be added so that the tests run for both. - */ + /** Tests run for both version 2 & version 3 */ protected val activatedVersions: Seq[Byte] = (0 to VersionContext.MaxSupportedScriptVersion).map(_.toByte).toArray[Byte] - private[sigma] val _currActivatedVersion = new DynamicVariable[Byte](2) // v5.x by default + private[sigma] val _currActivatedVersion = new DynamicVariable[Byte](3) // v6.x by default /** Current activated version used in tests. */ def activatedVersionInTests: Byte = _currActivatedVersion.value @@ -41,9 +39,10 @@ trait VersionTesting { _ + 1) { j => val treeVersion = ergoTreeVers(j) // for each tree version up to currently activated, set it up and execute block - _currErgoTreeVersion.withValue(treeVersion)(block) + _currErgoTreeVersion.withValue(treeVersion) { + VersionContext.withVersions(activatedVersion, treeVersion)(block) + } } - } } } diff --git a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala index 23406d9cb4..b05ee23e0d 100644 --- a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala @@ -233,6 +233,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { ), true) }, + { // SBigInt inherit methods from SNumericType.methods // however they are not resolvable via SBigInt.typeId import SNumericType._ From 815b224e5d506cc267b8672973bd19005e62f9d6 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 10 Apr 2024 19:36:19 +0300 Subject: [PATCH 05/25] importing tonbits method for playing with --- .../src/main/scala/sigma/VersionContext.scala | 6 +-- .../src/main/scala/sigma/ast/methods.scala | 38 ++++++++++++++----- .../MethodCallSerializerSpecification.scala | 10 +++++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 5663bfed60..19a4857086 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -1,6 +1,6 @@ package sigma -import VersionContext.{EvolutionVersion, JitActivationVersion} +import VersionContext.{JitActivationVersion, V6SoftForkVersion} import scala.util.DynamicVariable @@ -24,7 +24,7 @@ case class VersionContext(activatedVersion: Byte, ergoTreeVersion: Byte) { /** @return true, if the activated script version of Ergo protocol on the network is * including Evolution update. */ - def isEvolutionActivated: Boolean = activatedVersion >= EvolutionVersion + def isV6SoftForkActivated: Boolean = activatedVersion >= V6SoftForkVersion } object VersionContext { @@ -48,7 +48,7 @@ object VersionContext { /** * The version of ErgoTree corresponding to "evolution" (6.0) soft-fork */ - val EvolutionVersion: Byte = 3 + val V6SoftForkVersion: Byte = 3 private val _defaultContext = VersionContext( activatedVersion = 1 /* v4.x */, diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index b637acf792..321bbb0f05 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -2,7 +2,7 @@ package sigma.ast import org.ergoplatform._ import org.ergoplatform.validation._ -import sigma._ +import sigma.{VersionContext, _} import sigma.ast.SCollection.{SBooleanArray, SBoxArray, SByteArray, SByteArray2, SHeaderArray} import sigma.ast.SMethod.{MethodCallIrBuilder, MethodCostFunc, javaMethodOf} import sigma.ast.SType.TypeCode @@ -53,7 +53,7 @@ sealed trait MethodsContainer { protected def getMethods(): Seq[SMethod] = Nil /** Returns all the methods of this type. */ - lazy val methods: Seq[SMethod] = { + def methods: Seq[SMethod] = { //todo: consider versioned caching val ms = getMethods().toArray assert(ms.map(_.name).distinct.length == ms.length, s"Duplicate method names in $this") ms.groupBy(_.objType).foreach { case (comp, ms) => @@ -310,6 +310,13 @@ case object SBigIntMethods extends SNumericTypeMethods { /** Type for which this container defines methods. */ override def ownerType: SMonoType = SBigInt + final val ToNBitsCostInfo = OperationCostInfo( + FixedCost(JitCost(5)), NamedDesc("NBitsMethodCall")) + + //id = 8 to make it after toBits + val ToNBits = SMethod(this, "nbits", SFunc(this.ownerType, SLong), 8, ToNBitsCostInfo.costKind) + .withInfo(ModQ, "Encode this big integer value as NBits") + /** The following `modQ` methods are not fully implemented in v4.x and this descriptors. * This descritors are remain here in the code and are waiting for full implementation * is upcoming soft-forks at which point the cost parameters should be calculated and @@ -325,13 +332,26 @@ case object SBigIntMethods extends SNumericTypeMethods { .withIRInfo(MethodCallIrBuilder) .withInfo(MethodCall, "Multiply this number with \\lst{other} by module Q.", ArgInfo("other", "Number to multiply with this.")) - protected override def getMethods() = super.getMethods() ++ Seq( -// ModQMethod, -// PlusModQMethod, -// MinusModQMethod, - // TODO soft-fork: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/479 - // MultModQMethod, - ) + protected override def getMethods(): Seq[SMethod] = { + if (VersionContext.current.isV6SoftForkActivated) { + super.getMethods() ++ Seq(ToNBits) + // ModQMethod, + // PlusModQMethod, + // MinusModQMethod, + // TODO soft-fork: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/479 + // MultModQMethod, + } else { + super.getMethods() + } + } + + /** + * + */ + def nbits_eval(mc: MethodCall, bi: sigma.BigInt)(implicit E: ErgoTreeEvaluator): Long = { + ??? + } + } /** Methods of type `String`. */ diff --git a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala index ac9c997d98..e04f5e3746 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala @@ -21,4 +21,14 @@ class MethodCallSerializerSpecification extends SerializationSpecification { ) roundTripTest(expr) } + + property("MethodCall deserialization round trip for BigInt.nbits") { + val bi = BigIntConstant(5) + val expr = MethodCall(bi, + SBigIntMethods.ToNBits, + Vector(), + Map() + ) + roundTripTest(expr) + } } From 4fc62c67f7d7351d8ba075891b2c406ecd5598fb Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 11 Apr 2024 19:12:50 +0300 Subject: [PATCH 06/25] version test for nbits --- .../src/main/scala/sigma/ast/methods.scala | 2 +- .../MethodCallSerializerSpecification.scala | 28 ++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index 321bbb0f05..c6b71cd120 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -61,7 +61,7 @@ sealed trait MethodsContainer { } ms } - private lazy val _methodsMap: Map[Byte, Map[Byte, SMethod]] = methods + private def _methodsMap: Map[Byte, Map[Byte, SMethod]] = methods //todo: consider versioned caching .groupBy(_.objType.typeId) .map { case (typeId, ms) => (typeId -> ms.map(m => m.methodId -> m).toMap) } diff --git a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala index e04f5e3746..1db166c685 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala @@ -1,6 +1,8 @@ package sigma.serialization +import sigma.VersionContext import sigma.ast._ +import sigma.validation.ValidationException class MethodCallSerializerSpecification extends SerializationSpecification { @@ -23,12 +25,24 @@ class MethodCallSerializerSpecification extends SerializationSpecification { } property("MethodCall deserialization round trip for BigInt.nbits") { - val bi = BigIntConstant(5) - val expr = MethodCall(bi, - SBigIntMethods.ToNBits, - Vector(), - Map() - ) - roundTripTest(expr) + def code = { + val bi = BigIntConstant(5) + val expr = MethodCall(bi, + SBigIntMethods.ToNBits, + Vector(), + Map() + ) + roundTripTest(expr) + } + + VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { + code + } + + an[ValidationException] should be thrownBy ( + VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { + code + } + ) } } From 72814c0786c5c01b3d6904956d9da5129dfca4c7 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 1 May 2024 13:43:29 +0300 Subject: [PATCH 07/25] merging w. develop --- .../main/scala/sigma/js/GroupElement.scala | 4 +- .../src/main/scala/sigma/Environment.scala | 2 +- .../src/main/scala/sigma/Evaluation.scala | 3 +- .../src/main/scala/sigma/Extensions.scala | 11 ++-- .../src/main/scala/sigma/ast/SType.scala | 3 +- .../scala/sigma/data/SigmaPropCodes.scala | 2 +- .../src/main/scala/sigma/data/package.scala | 1 + .../shared/src/main/scala/sigma/package.scala | 7 ++- .../sigma/reflection/ReflectionData.scala | 10 ++- .../sigma/serialization/CoreByteReader.scala | 4 -- .../sigma/serialization/CoreByteWriter.scala | 3 + .../sigma/serialization/CoreSerializer.scala | 12 +++- .../scala/sigma/SigmaDataReflection.scala | 4 ++ .../src/main/scala/sigma/ast/CostItem.scala | 3 - .../src/main/scala/sigma/ast/SMethod.scala | 2 +- .../main/scala/sigma/ast/SigmaPredef.scala | 2 +- .../src/main/scala/sigma/ast/methods.scala | 11 ++-- .../src/main/scala/sigma/ast/syntax.scala | 2 - .../src/main/scala/sigma/ast/trees.scala | 1 - .../serialization/ErgoTreeSerializer.scala | 6 +- .../sigma/serialization/SigmaSerializer.scala | 4 +- .../interpreter/js/SigmaPropProver.scala | 1 - .../org/ergoplatform/ErgoLikeContext.scala | 1 - .../sigmastate/InterpreterReflection.scala | 4 ++ .../scala/sigmastate/crypto/GF2_192.scala | 2 - .../sigmastate/crypto/GF2_192_Poly.scala | 2 - .../main/scala/sigmastate/eval/CContext.scala | 56 ----------------- .../scala/sigmastate/eval/CProfiler.scala | 6 +- .../sigmastate/interpreter/Interpreter.scala | 7 +-- .../sigmastate/interpreter/ProverUtils.scala | 6 +- .../ConstantSerializerSpecification.scala | 2 +- .../DataSerializerSpecification.scala | 1 - .../scala/sigmastate/eval/BasicOpsTests.scala | 7 +-- .../special/sigma/ContractsTestkit.scala | 35 +---------- .../special/sigma/SigmaTestingData.scala | 63 +------------------ .../scala/sigmastate/lang/LangTests.scala | 1 - .../org/ergoplatform/dsl/ContractSyntax.scala | 2 +- .../main/scala/scalan/GraphIRReflection.scala | 4 ++ sc/shared/src/main/scala/scalan/Library.scala | 2 +- .../src/main/scala/scalan/MethodCalls.scala | 24 +------ .../src/main/scala/scalan/meta/SSymName.scala | 7 +-- .../scala/scalan/primitives/Functions.scala | 8 +-- .../main/scala/scalan/primitives/Thunks.scala | 2 +- .../scala/scalan/staged/Transforming.scala | 25 +++----- .../scala/sigmastate/eval/GraphBuilding.scala | 10 +-- .../scala/sigmastate/eval/IRContext.scala | 50 ++------------- .../scala/sigmastate/eval/SigmaLibrary.scala | 2 +- .../scala/sigmastate/eval/TreeBuilding.scala | 6 +- .../scala/sigmastate/lang/SigmaBinder.scala | 1 - .../scala/special/collection/CollsUnit.scala | 5 -- .../special/sigma/impl/SigmaDslImpl.scala | 17 +---- .../src/test/scala/scalan/LibraryTests.scala | 2 +- .../scala/sigma/SigmaDslStaginTests.scala | 4 +- .../sigmastate/ErgoTreeSpecification.scala | 1 - .../SoftForkabilitySpecification.scala | 4 +- .../TestingInterpreterSpecification.scala | 11 ++-- .../sigmastate/eval/ErgoScriptTestkit.scala | 39 ++++++++---- .../sigmastate/eval/EvaluationTest.scala | 18 ------ .../sigmastate/eval/MeasureIRContext.scala | 36 ----------- .../helpers/CompilerTestingCommons.scala | 3 +- .../utxo/BasicOpsSpecification.scala | 4 +- .../org/ergoplatform/sdk/Extensions.scala | 26 -------- .../org/ergoplatform/sdk/ExtensionsSpec.scala | 11 ++-- 63 files changed, 149 insertions(+), 466 deletions(-) delete mode 100644 sc/shared/src/test/scala/sigmastate/eval/MeasureIRContext.scala diff --git a/core/js/src/main/scala/sigma/js/GroupElement.scala b/core/js/src/main/scala/sigma/js/GroupElement.scala index 21b53b265d..82d8d462d6 100644 --- a/core/js/src/main/scala/sigma/js/GroupElement.scala +++ b/core/js/src/main/scala/sigma/js/GroupElement.scala @@ -1,6 +1,6 @@ package sigma.js -import sigma.Extensions.CoreArrayByteOps +import scorex.util.encode.Base16 import sigma.crypto.{CryptoFacade, CryptoFacadeJs, Ecp, Platform} import scala.scalajs.js @@ -13,7 +13,7 @@ class GroupElement(val point: Ecp) extends js.Object { * @see CryptoFacade.getASN1Encoding */ def toPointHex(): String = { - CryptoFacade.getASN1Encoding(point, true).toHex + Base16.encode(CryptoFacade.getASN1Encoding(point, true)) } } diff --git a/core/shared/src/main/scala/sigma/Environment.scala b/core/shared/src/main/scala/sigma/Environment.scala index 959e02c1fb..432c40110c 100644 --- a/core/shared/src/main/scala/sigma/Environment.scala +++ b/core/shared/src/main/scala/sigma/Environment.scala @@ -14,7 +14,7 @@ sealed abstract class Environment { object Environment { /** Current runtime environment. */ - implicit val current: Environment = new Environment { + val current: Environment = new Environment { override def isJVM: Boolean = runtimePlatform == RuntimePlatform.JVM override def isJS: Boolean = runtimePlatform == RuntimePlatform.JS override def runtimePlatform: RuntimePlatform = sigma.reflection.Platform.runtimePlatform diff --git a/core/shared/src/main/scala/sigma/Evaluation.scala b/core/shared/src/main/scala/sigma/Evaluation.scala index 893bdfb9f8..d86b7c1650 100644 --- a/core/shared/src/main/scala/sigma/Evaluation.scala +++ b/core/shared/src/main/scala/sigma/Evaluation.scala @@ -76,8 +76,7 @@ object Evaluation { case HeaderRType => SHeader case PreHeaderRType => SPreHeader case SigmaPropRType => SSigmaProp - // TODO remove commented code below after full sync test - // case SigmaBooleanRType => SSigmaProp // this is not used in consensus code + case SigmaBooleanRType => SSigmaProp // TODO remove: this is not used in consensus code case tup: TupleType => STuple(tup.items.map(t => rtypeToSType(t))) case at: ArrayType[_] => SCollection(rtypeToSType(at.tA)) case ct: CollType[_] => SCollection(rtypeToSType(ct.tItem)) diff --git a/core/shared/src/main/scala/sigma/Extensions.scala b/core/shared/src/main/scala/sigma/Extensions.scala index 865d488803..0c79df94ea 100644 --- a/core/shared/src/main/scala/sigma/Extensions.scala +++ b/core/shared/src/main/scala/sigma/Extensions.scala @@ -5,13 +5,14 @@ import scorex.util.encode.Base16 import scorex.util.{ModifierId, bytesToId} import sigma.data.RType +/** Declaration of extension methods introduced in `sigma-core` module. + * See `implicit class ...` wrappers below. + */ object Extensions { - /** Extension methods for `Array[Byte]` not available for generic `Array[T]`. */ - implicit class CoreArrayByteOps(val arr: Array[Byte]) extends AnyVal { - /** Encodes array into hex string */ - @inline def toHex: String = Base16.encode(arr) - } + /** Extension methods for `Array[T]` where implicit descriptor `RType[T]` is also + * required. + */ implicit class ArrayOps[T: RType](arr: Array[T]) { /** Wraps array into Coll instance. The source array in not cloned. */ @inline def toColl: Coll[T] = Colls.fromArray(arr) diff --git a/core/shared/src/main/scala/sigma/ast/SType.scala b/core/shared/src/main/scala/sigma/ast/SType.scala index e9ea0d43f0..f75cbc9e8b 100644 --- a/core/shared/src/main/scala/sigma/ast/SType.scala +++ b/core/shared/src/main/scala/sigma/ast/SType.scala @@ -94,7 +94,6 @@ object SType { val paramOV = STypeParam(tOV) val paramIVSeq: Seq[STypeParam] = Array(paramIV) - val IndexedSeqOfT1: IndexedSeq[SType] = Array(SType.tT) val IndexedSeqOfT2: IndexedSeq[SType] = Array(SType.tT, SType.tT) /** Immutable empty array, can be used to avoid repeated allocations. */ @@ -146,7 +145,7 @@ object SType { * 2) `isValueOfType == true` for each tree leaf * 3) `isValueOfType == true` for each sub-expression * - * @param value value to check type + * @param x value to check type * @param tpe type descriptor to check value against * @return true if the given `value` is of type tpe` */ diff --git a/core/shared/src/main/scala/sigma/data/SigmaPropCodes.scala b/core/shared/src/main/scala/sigma/data/SigmaPropCodes.scala index 17257c9ce5..fafd24ffdd 100644 --- a/core/shared/src/main/scala/sigma/data/SigmaPropCodes.scala +++ b/core/shared/src/main/scala/sigma/data/SigmaPropCodes.scala @@ -3,7 +3,7 @@ package sigma.data import sigma.ast.TypeCodes.LastConstantCode import supertagged.TaggedType -/** Encoding of sigma proposition nodes. +/** Opcodes of sigma proposition nodes. * * @see SigmaBoolean.opCode */ diff --git a/core/shared/src/main/scala/sigma/data/package.scala b/core/shared/src/main/scala/sigma/data/package.scala index a0fb219af8..c5a35f7b5f 100644 --- a/core/shared/src/main/scala/sigma/data/package.scala +++ b/core/shared/src/main/scala/sigma/data/package.scala @@ -16,6 +16,7 @@ package object data { val BigIntClassTag = classTag[BigInt] val GroupElementClassTag = classTag[GroupElement] val SigmaPropClassTag = classTag[SigmaProp] + val SigmaBooleanClassTag = classTag[SigmaBoolean] val AvlTreeClassTag = classTag[AvlTree] val BoxClassTag = classTag[Box] val ContextClassTag = classTag[Context] diff --git a/core/shared/src/main/scala/sigma/package.scala b/core/shared/src/main/scala/sigma/package.scala index 67560b462c..89b883f52d 100644 --- a/core/shared/src/main/scala/sigma/package.scala +++ b/core/shared/src/main/scala/sigma/package.scala @@ -25,9 +25,12 @@ package object sigma { implicit val StringType : RType[String] = GeneralType(StringClassTag) - implicit val BigIntRType: RType[BigInt] = GeneralType(BigIntClassTag) + implicit val BigIntRType : RType[BigInt] = GeneralType(BigIntClassTag) implicit val GroupElementRType: RType[GroupElement] = GeneralType(GroupElementClassTag) - implicit val SigmaPropRType: RType[SigmaProp] = GeneralType(SigmaPropClassTag) + implicit val SigmaPropRType : RType[SigmaProp] = GeneralType(SigmaPropClassTag) + implicit val SigmaBooleanRType: RType[SigmaBoolean] = GeneralType(SigmaBooleanClassTag) + + implicit val AvlTreeRType: RType[AvlTree] = GeneralType(AvlTreeClassTag) implicit val BoxRType: RType[Box] = GeneralType(BoxClassTag) diff --git a/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala b/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala index 2aac1a5670..028e68bf72 100644 --- a/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala +++ b/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala @@ -9,9 +9,15 @@ import scala.collection.mutable import scala.collection.immutable /** Reflection metadata and global dictionaries to access it. - * For each class of this module that needs reflection metadata, - * we register a class entry with the necessary information. + * Such metadata is only used on JS platform to support reflection-like interfaces of + * RClass, RMethod, RConstructor. These interfaces implemented on JVM using Java + * reflection. + * + * For each class that needs reflection metadata, we register a class entry using + * `registerClassEntry` method with the necessary information such as constructors and + * methods. * Only information that is needed at runtime is registered. + * @see mkConstructor, mkMethod */ object ReflectionData { /** Descriptors of classes. */ diff --git a/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala b/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala index 34ed74ac6a..e238829b6c 100644 --- a/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala +++ b/core/shared/src/main/scala/sigma/serialization/CoreByteReader.scala @@ -10,10 +10,6 @@ import sigma.validation.ValidationRules.CheckPositionLimit * methods. * * @param r the underlying reader this reader reads from - * @param constantStore the store of constants which is used to resolve - * [[sigma.ast.ConstantPlaceholder]] - * @param resolvePlaceholdersToConstants if true then resolved constants will be - * substituted in the tree instead of the placeholder. * @param maxTreeDepth limit on the tree depth (recursive invocations) * of the deserializer */ diff --git a/core/shared/src/main/scala/sigma/serialization/CoreByteWriter.scala b/core/shared/src/main/scala/sigma/serialization/CoreByteWriter.scala index d6cc9a8d8e..aa4255449c 100644 --- a/core/shared/src/main/scala/sigma/serialization/CoreByteWriter.scala +++ b/core/shared/src/main/scala/sigma/serialization/CoreByteWriter.scala @@ -5,6 +5,9 @@ import scorex.util.serialization.{VLQByteBufferWriter, Writer} import sigma.ast.SType import sigma.serialization.CoreByteWriter.{Bits, DataInfo, U, Vlq, ZigZag} +/** Implementation of [[Writer]] provided by `sigma-core` module. + * @param w destination [[Writer]] to which all the call got delegated. + */ class CoreByteWriter(val w: Writer) extends Writer { type CH = w.CH diff --git a/core/shared/src/main/scala/sigma/serialization/CoreSerializer.scala b/core/shared/src/main/scala/sigma/serialization/CoreSerializer.scala index aec82eb9df..938d3f22c1 100644 --- a/core/shared/src/main/scala/sigma/serialization/CoreSerializer.scala +++ b/core/shared/src/main/scala/sigma/serialization/CoreSerializer.scala @@ -6,25 +6,31 @@ import sigma.data.SigmaConstants import java.nio.ByteBuffer +/** Implementation of [[Serializer]] provided by `sigma-core` module. */ abstract class CoreSerializer[TFamily, T <: TFamily] extends Serializer[TFamily, T, CoreByteReader, CoreByteWriter] { - def error(msg: String) = throw new SerializerException(msg, None) + def error(msg: String) = throw SerializerException(msg, None) + /** Serializes the given 'obj' to a new array of bytes using this serializer. */ final def toBytes(obj: T): Array[Byte] = { val w = CoreSerializer.startWriter() serialize(obj, w) w.toBytes } + /** Deserializes `bytes` to an object of this [[TFamily]] using this serializer. + * The actual class of the returned object is expected to be descendant of [[TFamily]]. + */ final def fromBytes(bytes: Array[Byte]): TFamily = { parse(CoreSerializer.startReader(bytes)) } } object CoreSerializer { - type Position = Int - + /** Max length of Box.propositionBytes collection */ val MaxPropositionSize: Int = SigmaConstants.MaxPropositionBytes.value + + /** Max tree depth should not be greater then provided value */ val MaxTreeDepth: Int = SigmaConstants.MaxTreeDepth.value /** Helper function to be use in serializers. diff --git a/data/shared/src/main/scala/sigma/SigmaDataReflection.scala b/data/shared/src/main/scala/sigma/SigmaDataReflection.scala index 31703b0856..48939b1460 100644 --- a/data/shared/src/main/scala/sigma/SigmaDataReflection.scala +++ b/data/shared/src/main/scala/sigma/SigmaDataReflection.scala @@ -11,6 +11,10 @@ import sigma.reflection.{ReflectionData, mkConstructor, mkMethod} import sigma.serialization.ValueCodes.OpCode /** Reflection metadata for `interpreter` module. + * Such metadata is only used on JS platform to support reflection-like interfaces of + * RClass, RMethod, RConstructor. These interfaces implemented on JVM using Java + * reflection. + * * For each class of this module that needs reflection metadata, * we register a class entry with the necessary information. * Only information that is needed at runtime is registered. diff --git a/data/shared/src/main/scala/sigma/ast/CostItem.scala b/data/shared/src/main/scala/sigma/ast/CostItem.scala index 8fa973b575..c69c81daa3 100644 --- a/data/shared/src/main/scala/sigma/ast/CostItem.scala +++ b/data/shared/src/main/scala/sigma/ast/CostItem.scala @@ -1,8 +1,5 @@ package sigma.ast -import sigma.ast -import sigma.eval.CostDetails - /** An item in the cost accumulation trace of a [[sigma.ast.ErgoTree]] evaluation. */ abstract class CostItem { def opName: String diff --git a/data/shared/src/main/scala/sigma/ast/SMethod.scala b/data/shared/src/main/scala/sigma/ast/SMethod.scala index 2d306d8948..669625ef1e 100644 --- a/data/shared/src/main/scala/sigma/ast/SMethod.scala +++ b/data/shared/src/main/scala/sigma/ast/SMethod.scala @@ -105,7 +105,7 @@ case class SMethod( /** Invoke this method on the given object with the arguments. * This is used for methods with FixedCost costKind. */ - def invokeFixed(obj: Any, args: Array[Any])(implicit E: ErgoTreeEvaluator): Any = { + def invokeFixed(obj: Any, args: Array[Any]): Any = { javaMethod.invoke(obj, args.asInstanceOf[Array[AnyRef]]:_*) } diff --git a/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala b/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala index 5cdbdedaa8..c4bc32e4a5 100644 --- a/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala +++ b/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala @@ -591,7 +591,7 @@ object SigmaPredef { ).map(f => f.name -> f).toMap private val funcNameToIrBuilderMap: Map[String, PredefinedFunc] = - funcs.filter { case (n, f) => f.irInfo.irBuilder != undefined } + funcs.filter { case (_, f) => f.irInfo.irBuilder != undefined } def irBuilderForFunc(name: String): Option[IrBuilderFunc] = funcNameToIrBuilderMap.get(name).map(_.irInfo.irBuilder) } diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index c6b71cd120..e4cf0007e0 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -2,7 +2,7 @@ package sigma.ast import org.ergoplatform._ import org.ergoplatform.validation._ -import sigma.{VersionContext, _} +import sigma._ import sigma.ast.SCollection.{SBooleanArray, SBoxArray, SByteArray, SByteArray2, SHeaderArray} import sigma.ast.SMethod.{MethodCallIrBuilder, MethodCostFunc, javaMethodOf} import sigma.ast.SType.TypeCode @@ -15,7 +15,6 @@ import sigma.serialization.CoreByteWriter.ArgInfo import sigma.utils.SparseArrayContainer import scala.annotation.unused -import scala.language.implicitConversions /** Base type for all companions of AST nodes of sigma lang. */ trait SigmaNodeCompanion @@ -235,7 +234,7 @@ object SNumericTypeMethods extends MethodsContainer { | Each boolean corresponds to one bit. """.stripMargin) - protected override def getMethods: Seq[SMethod] = Array( + protected override def getMethods(): Seq[SMethod] = Array( ToByteMethod, // see Downcast ToShortMethod, // see Downcast ToIntMethod, // see Downcast @@ -740,7 +739,7 @@ object SCollectionMethods extends MethodsContainer with MethodByNameUnapply { * of flatMap. Other bodies are rejected with throwing exception. */ val flatMap_BodyPatterns = Array[PartialFunction[SValue, Int]]( - { case MethodCall(ValUse(id, tpe), m, args, _) if args.isEmpty => id }, + { case MethodCall(ValUse(id, _), _, args, _) if args.isEmpty => id }, { case ExtractScriptBytes(ValUse(id, _)) => id }, { case ExtractId(ValUse(id, _)) => id }, { case SigmaPropBytes(ValUse(id, _)) => id }, @@ -786,7 +785,7 @@ object SCollectionMethods extends MethodsContainer with MethodByNameUnapply { var res: Nullable[(Int, SValue)] = Nullable.None E.addFixedCost(MatchSingleArgMethodCall_Info) { res = mc match { - case MethodCall(_, m, Seq(FuncValue(args, body)), _) if args.length == 1 => + case MethodCall(_, _, Seq(FuncValue(args, body)), _) if args.length == 1 => val id = args(0)._1 Nullable((id, body)) case _ => @@ -1500,7 +1499,7 @@ case object SGlobalMethods extends MonoTypeMethods { lazy val groupGeneratorMethod = SMethod( this, "groupGenerator", SFunc(SGlobal, SGroupElement), 1, GroupGenerator.costKind) - .withIRInfo({ case (builder, obj, method, args, tparamSubst) => GroupGenerator }) + .withIRInfo({ case (_, _, _, _, _) => GroupGenerator }) .withInfo(GroupGenerator, "") lazy val xorMethod = SMethod( diff --git a/data/shared/src/main/scala/sigma/ast/syntax.scala b/data/shared/src/main/scala/sigma/ast/syntax.scala index d75c71a779..5a257481cb 100644 --- a/data/shared/src/main/scala/sigma/ast/syntax.scala +++ b/data/shared/src/main/scala/sigma/ast/syntax.scala @@ -118,8 +118,6 @@ object syntax { @nowarn private def rtypeToClassTag = ??? /** RType descriptors for predefined types used in AOTC-based interpreter. */ - implicit val SigmaBooleanRType: RType[SigmaBoolean] = RType.fromClassTag(classTag[SigmaBoolean]) - implicit val ErgoBoxRType: RType[ErgoBox] = RType.fromClassTag(classTag[ErgoBox]) implicit val ErgoBoxCandidateRType: RType[ErgoBoxCandidate] = RType.fromClassTag(classTag[ErgoBoxCandidate]) diff --git a/data/shared/src/main/scala/sigma/ast/trees.scala b/data/shared/src/main/scala/sigma/ast/trees.scala index 38d4565f30..39e666a389 100644 --- a/data/shared/src/main/scala/sigma/ast/trees.scala +++ b/data/shared/src/main/scala/sigma/ast/trees.scala @@ -295,7 +295,6 @@ object AND extends LogicalTransformerCompanion { def apply(children: Seq[Value[SBoolean.type]]): AND = AND(ConcreteCollection.fromSeq(children)) -// def apply(head: Value[SBoolean.type], tail: Value[SBoolean.type]*): AND = apply(head +: tail) def apply(items: Value[SBoolean.type]*)(implicit o1: Overloaded1): AND = apply(items) } diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 3d1061d774..43e41f91ff 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -1,13 +1,13 @@ package sigma.serialization import org.ergoplatform.validation.ValidationRules.{CheckDeserializedScriptIsSigmaProp, CheckHeaderSizeBit} -import sigma.ast.{Constant, DeserializationSigmaBuilder, ErgoTree, SType, SubstConstants, UnparsedErgoTree} +import sigma.ast.{Constant, DeserializationSigmaBuilder, ErgoTree, SType, UnparsedErgoTree} import sigma.ast.syntax.ValueOps import sigma.ast.ErgoTree.{EmptyConstants, HeaderType} import sigma.util.safeNewArray import debox.cfor import sigma.VersionContext -import sigma.validation.{SigmaValidationSettings, ValidationException} +import sigma.validation.ValidationException import sigma.validation.ValidationRules.CheckPositionLimit /** @@ -299,7 +299,7 @@ class ErgoTreeSerializer { */ def substituteConstants(scriptBytes: Array[Byte], positions: Array[Int], - newVals: Array[Constant[SType]])(implicit vs: SigmaValidationSettings): (Array[Byte], Int) = { + newVals: Array[Constant[SType]]): (Array[Byte], Int) = { require(positions.length == newVals.length, s"expected positions and newVals to have the same length, got: positions: ${positions.toSeq},\n newVals: ${newVals.toSeq}") val r = SigmaSerializer.startReader(scriptBytes) diff --git a/data/shared/src/main/scala/sigma/serialization/SigmaSerializer.scala b/data/shared/src/main/scala/sigma/serialization/SigmaSerializer.scala index cdb28d724b..3765adb029 100644 --- a/data/shared/src/main/scala/sigma/serialization/SigmaSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/SigmaSerializer.scala @@ -4,7 +4,6 @@ import java.nio.ByteBuffer import scorex.util.ByteArrayBuilder import scorex.util.serialization._ import sigma.data.SigmaConstants -import sigma.validation.SigmaValidationSettings import sigma.serialization.ValueCodes.OpCode object SigmaSerializer { @@ -35,8 +34,7 @@ object SigmaSerializer { /** Helper function to be use in serializers. */ def startReader(bytes: Array[Byte], constantStore: ConstantStore, - resolvePlaceholdersToConstants: Boolean) - (implicit vs: SigmaValidationSettings): SigmaByteReader = { + resolvePlaceholdersToConstants: Boolean): SigmaByteReader = { val buf = ByteBuffer.wrap(bytes) val r = new SigmaByteReader(new VLQByteBufferReader(buf), constantStore, diff --git a/interpreter/js/src/main/scala/sigma/interpreter/js/SigmaPropProver.scala b/interpreter/js/src/main/scala/sigma/interpreter/js/SigmaPropProver.scala index a04d32fa54..414a9d1220 100644 --- a/interpreter/js/src/main/scala/sigma/interpreter/js/SigmaPropProver.scala +++ b/interpreter/js/src/main/scala/sigma/interpreter/js/SigmaPropProver.scala @@ -65,7 +65,6 @@ class SigmaPropProver(override val wrappedValue: org.ergoplatform.SigmaPropProve val realsToExtract = toSigmaBooleanSeq(realSecretsToExtract) val simsToExtract = toSigmaBooleanSeq(simulatedSecretsToExtract) val hints = wrappedValue.bagForMultisig( - context = null, sigmaTree = sigmaTree.sigmaBoolean, proof.toArray, realSecretsToExtract = realsToExtract, simulatedSecretsToExtract = simsToExtract) diff --git a/interpreter/shared/src/main/scala/org/ergoplatform/ErgoLikeContext.scala b/interpreter/shared/src/main/scala/org/ergoplatform/ErgoLikeContext.scala index 8468175631..e421e8fdfe 100644 --- a/interpreter/shared/src/main/scala/org/ergoplatform/ErgoLikeContext.scala +++ b/interpreter/shared/src/main/scala/org/ergoplatform/ErgoLikeContext.scala @@ -6,7 +6,6 @@ import sigma.ast.SType.{AnyOps, TypeCode} import sigma.ast._ import sigma.data.{AvlTreeData, CAvlTree, CSigmaDslBuilder, SigmaConstants} import sigma.eval.Extensions.toAnyValue -import sigma.exceptions.InterpreterException import sigma.interpreter.ContextExtension import sigma.validation.SigmaValidationSettings import sigma.{AnyValue, Coll, Header, PreHeader} diff --git a/interpreter/shared/src/main/scala/sigmastate/InterpreterReflection.scala b/interpreter/shared/src/main/scala/sigmastate/InterpreterReflection.scala index 8b18e20459..9a06322166 100644 --- a/interpreter/shared/src/main/scala/sigmastate/InterpreterReflection.scala +++ b/interpreter/shared/src/main/scala/sigmastate/InterpreterReflection.scala @@ -8,6 +8,10 @@ import sigmastate.crypto.GF2_192_Poly import sigmastate.crypto.VerifierMessage.Challenge /** Reflection metadata for `interpreter` module. + * Such metadata is only used on JS platform to support reflection-like interfaces of + * RClass, RMethod, RConstructor. These interfaces implemented on JVM using Java + * reflection. + * * For each class of this module that needs reflection metadata, * we register a class entry with the necessary information. * Only information that is needed at runtime is registered. diff --git a/interpreter/shared/src/main/scala/sigmastate/crypto/GF2_192.scala b/interpreter/shared/src/main/scala/sigmastate/crypto/GF2_192.scala index bb0ad60a84..e63526e854 100644 --- a/interpreter/shared/src/main/scala/sigmastate/crypto/GF2_192.scala +++ b/interpreter/shared/src/main/scala/sigmastate/crypto/GF2_192.scala @@ -30,8 +30,6 @@ package sigmastate.crypto import debox.cfor -import java.util - class GF2_192 extends AnyRef { private[crypto] val word: Array[Long] = new Array[Long](3) diff --git a/interpreter/shared/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala b/interpreter/shared/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala index a9212fe565..d2ddc4db48 100644 --- a/interpreter/shared/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala +++ b/interpreter/shared/src/main/scala/sigmastate/crypto/GF2_192_Poly.scala @@ -31,8 +31,6 @@ package sigmastate.crypto import debox.cfor -import java.util - class GF2_192_Poly { final private var c: Array[GF2_192] = null // must be not null and of length at least 1 diff --git a/interpreter/shared/src/main/scala/sigmastate/eval/CContext.scala b/interpreter/shared/src/main/scala/sigmastate/eval/CContext.scala index 418f9e8959..2b076403ad 100644 --- a/interpreter/shared/src/main/scala/sigmastate/eval/CContext.scala +++ b/interpreter/shared/src/main/scala/sigmastate/eval/CContext.scala @@ -9,62 +9,6 @@ import sigma.exceptions.InvalidType import scala.annotation.unused import scala.reflect.ClassTag - -/** This class represents context variable and register value of a functional type A => B. - * When variable or register is accessed using `getVar[A => B](id).get` or - * `box.getReg[A => B].get an instance of this class is returned. - * - * It internally transforms a given `tree` into executable function. - * This it similar to what happens during validation of propositions in the input boxes: - * - size check of underlying ErgoTree against limits - * - construction of `calcF` and `costF` graphs, both are stored together with resulting function. - * - check the types of `calcF` graph to be compatible with expected types A and B - * If anything goes wrong, this operation fails and if it is used in the script, the script also fails. - * - * When f is obtained as `val f = getVar[Int => Int](id).get` then any application `f(x)` involves size estimation - * using underlying `costF(x)`. - * */ -//case class CFunc[A,B](context: sigmastate.interpreter.Context, tree: SValue) -// (implicit tDom: RType[A], tRange: RType[B], IR: IRContext) extends (A => B) { -// import CFunc._ -// -// private val compiled = { -// import IR._ -// val IR.Pair(calcF, costF) = IR.doCosting(emptyEnv, tree) -// -// val eDom = asElem[Any](IR.rtypeToElem(tDom)) -// val eRange = asElem[Any](IR.rtypeToElem(tRange)) -// -// IR.verifyCalcFunc[Any => Any](asRep[Context => (Any => Any)](calcF), IR.funcElement(eDom, eRange)) -//// IR.verifyCostFunc(costF).getOrThrow -//// IR.verifyIsProven(calcF).getOrThrow -// -// // check cost -//// val costingCtx = context.toSigmaContext(IR, isCost = true) -//// val costFun = IR.compile[SInt.type](IR.getDataEnv, costF) -//// val IntConstant(estimatedCost) = costFun(costingCtx) -//// if (estimatedCost > maxCost) { -//// throw new Error(s"Estimated execution cost $estimatedCost exceeds the limit $maxCost in $tree") -//// } -// // check calc -// val calcCtx = context.toSigmaContext(IR, isCost = false) -// val valueFun = IR.compile[SFunc](IR.getDataEnv, asRep[Context => SFunc#WrappedType](calcF)) -// val res = valueFun(calcCtx) match { -// case Constant(f, fTpe: SFunc) => f -// case v => v -// } -// res.asInstanceOf[A => B] -// } -// -// override def apply(x: A): B = compiled(x) -//} -object CFunc { - /** The cost of creating resulting function but not its execution. - * Thus it is expected to be small. It can be increased if useful cases are found - * such that `tree` should contains heavy operations. */ - val maxCost = 1000 -} - /** A default implementation of [[Context]] interface. * @see [[Context]] for detailed descriptions */ diff --git a/interpreter/shared/src/main/scala/sigmastate/eval/CProfiler.scala b/interpreter/shared/src/main/scala/sigmastate/eval/CProfiler.scala index ced8a357b8..d07153bd51 100644 --- a/interpreter/shared/src/main/scala/sigmastate/eval/CProfiler.scala +++ b/interpreter/shared/src/main/scala/sigmastate/eval/CProfiler.scala @@ -280,7 +280,7 @@ class CProfiler extends Profiler { case ci: TypeBasedCostItem => val comment = s"count: $count, suggested: $suggestedCost, actCost: ${ci.cost}$warn" (ci.opName, time, time, comment) - case ci @ SeqCostItem(_, costKind, nItems) => + case ci @ SeqCostItem(_, costKind, _) => val nChunks = ci.chunks val timePerChunk = if (nChunks > 0) time / nChunks else time val name = s"${ci.opName}(nChunks: $nChunks)" @@ -289,7 +289,7 @@ class CProfiler extends Profiler { } } (name, timePerItem, time, comment) - }.sortBy({ case (name, tpi, t, c) => (name, tpi)})(Ordering[(String, Long)]) + }.sortBy({ case (name, tpi, _, _) => (name, tpi)})(Ordering[(String, Long)]) val estLines = estimationCostStat.mapToArray { case (script, stat) => val (cost, count) = stat.mean @@ -302,7 +302,7 @@ class CProfiler extends Profiler { val rows = opCodeLines - .map { case (opName, opCode, time, comment) => + .map { case (opName, _, time, comment) => val key = s"$opName".padTo(26, ' ') s"$key -> time: $time ns, $comment " } diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala index 6b673038c7..9a1ab11f0e 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -23,7 +23,7 @@ import sigmastate.interpreter.CErgoTreeEvaluator.fixedCostOp import sigmastate.interpreter.Interpreter._ import sigma.ast.syntax.ValueOps import sigma.eval.{EvalSettings, SigmaDsl} -import sigma.exceptions.{CostLimitException, InterpreterException} +import sigma.exceptions.InterpreterException import sigma.interpreter.ProverResult import sigma.util.CollectionUtil import sigmastate.utils.Helpers._ @@ -164,12 +164,11 @@ trait Interpreter { * else `exp` is computed in the given context and the resulting SigmaBoolean returned. * * @param context the context in which `exp` should be executed - * @param env environment of system variables used by the interpreter internally * @param exp expression to be executed in the given `context` * @return result of script reduction * @see `ReductionResult` */ - protected def reduceToCryptoJITC(context: CTX, env: ScriptEnv, exp: SigmaPropValue): Try[ReductionResult] = Try { + protected def reduceToCryptoJITC(context: CTX, exp: SigmaPropValue): Try[ReductionResult] = Try { implicit val vs = context.validationSettings trySoftForkable[ReductionResult](whenSoftFork = WhenSoftForkReductionResult(context.initCost)) { @@ -253,7 +252,7 @@ trait Interpreter { // here we assume that when `propTree` is TrueProp then `reduceToCrypto` always succeeds // and the rest of the verification is also trivial - reduceToCryptoJITC(context2, env, propTree).getOrThrow + reduceToCryptoJITC(context2, propTree).getOrThrow } res diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/ProverUtils.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/ProverUtils.scala index 15daaec382..dc2259b0b7 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/ProverUtils.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/ProverUtils.scala @@ -81,7 +81,7 @@ trait ProverUtils extends Interpreter { realSecretsToExtract: Seq[SigmaBoolean], simulatedSecretsToExtract: Seq[SigmaBoolean] = Seq.empty): HintsBag = { val reduced = fullReduction(ergoTree, context, Interpreter.emptyEnv) - bagForMultisig(context, reduced.value, proof, realSecretsToExtract, simulatedSecretsToExtract) + bagForMultisig(reduced.value, proof, realSecretsToExtract, simulatedSecretsToExtract) } /** @@ -90,15 +90,13 @@ trait ProverUtils extends Interpreter { * * See DistributedSigSpecification for examples of usage. * - * @param context - context used to reduce the proposition * @param sigmaTree - public key (in form of a sigma-tree) * @param proof - signature for the key * @param realSecretsToExtract - public keys of secrets with real proofs * @param simulatedSecretsToExtract - public keys of secrets with simulated proofs * @return - bag of OtherSecretProven and OtherCommitment hints */ - def bagForMultisig(context: CTX, - sigmaTree: SigmaBoolean, + def bagForMultisig(sigmaTree: SigmaBoolean, proof: Array[Byte], realSecretsToExtract: Seq[SigmaBoolean], simulatedSecretsToExtract: Seq[SigmaBoolean]): HintsBag = { diff --git a/interpreter/shared/src/test/scala/sigma/serialization/ConstantSerializerSpecification.scala b/interpreter/shared/src/test/scala/sigma/serialization/ConstantSerializerSpecification.scala index 7bc73643f2..43e9cf9e5d 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/ConstantSerializerSpecification.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/ConstantSerializerSpecification.scala @@ -61,7 +61,7 @@ class ConstantSerializerSpecification extends TableSerializationSpecification { } property("Constant serialization round trip") { - forAll { x: Unit => roundTripTest(UnitConstant()) } + forAll { _: Unit => roundTripTest(UnitConstant()) } forAll { x: Byte => roundTripTest(Constant[SByte.type](x, SByte)) } forAll { x: Boolean => roundTripTest(BooleanConstant.fromBoolean(x)) } forAll { x: Long => roundTripTest(Constant[SLong.type](x, SLong)) } diff --git a/interpreter/shared/src/test/scala/sigma/serialization/DataSerializerSpecification.scala b/interpreter/shared/src/test/scala/sigma/serialization/DataSerializerSpecification.scala index ecb2d2ef70..7cd9967e54 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/DataSerializerSpecification.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/DataSerializerSpecification.scala @@ -5,7 +5,6 @@ import org.ergoplatform.ErgoBox import org.scalacheck.Arbitrary._ import sigma.data.{DataValueComparer, RType, SigmaBoolean, TupleColl} import sigma.ast.SCollection.SByteArray -import sigmastate._ import sigmastate.eval._ import sigma.{AvlTree, Colls, Evaluation} import sigma.ast.SType.AnyOps diff --git a/interpreter/shared/src/test/scala/sigmastate/eval/BasicOpsTests.scala b/interpreter/shared/src/test/scala/sigmastate/eval/BasicOpsTests.scala index ba996b0246..e9ba273e17 100644 --- a/interpreter/shared/src/test/scala/sigmastate/eval/BasicOpsTests.scala +++ b/interpreter/shared/src/test/scala/sigmastate/eval/BasicOpsTests.scala @@ -3,16 +3,15 @@ package sigmastate.eval import org.scalatest.funsuite.AnyFunSuite import org.scalatest.matchers.should.Matchers import sigma.crypto.SecP256K1Group -import sigma.data.{CSigmaDslBuilder, TrivialProp} +import sigma.data.{CSigmaDslBuilder => SigmaDsl, TrivialProp} import sigma.util.Extensions.SigmaBooleanOps import java.math.BigInteger -import sigma.{ContractsTestkit, SigmaDslBuilder, SigmaProp} +import sigma.{ContractsTestkit, SigmaProp} import scala.language.implicitConversions class BasicOpsTests extends AnyFunSuite with ContractsTestkit with Matchers { - override val SigmaDsl: SigmaDslBuilder = CSigmaDslBuilder implicit def boolToSigma(b: Boolean): SigmaProp = TrivialProp(b).toSigmaProp @@ -60,7 +59,7 @@ class BasicOpsTests extends AnyFunSuite with ContractsTestkit with Matchers { } test("box.creationInfo._1 is Int") { - val box = newAliceBox(1, 100) + val box = newAliceBox(100) box.creationInfo._1 shouldBe a [Integer] } diff --git a/interpreter/shared/src/test/scala/special/sigma/ContractsTestkit.scala b/interpreter/shared/src/test/scala/special/sigma/ContractsTestkit.scala index 720223ee3a..b04e9c150f 100644 --- a/interpreter/shared/src/test/scala/special/sigma/ContractsTestkit.scala +++ b/interpreter/shared/src/test/scala/special/sigma/ContractsTestkit.scala @@ -8,43 +8,18 @@ import sigmastate.eval._ import sigmastate.helpers.TestingHelpers._ import sigma.data._ -import scala.annotation.nowarn // imports implicit ClassTag - trait ContractsTestkit { - val R0 = 0.toByte; - val R1 = 1.toByte; - val R2 = 2.toByte; - val R3 = 3.toByte; - val R4 = 4.toByte; - val R5 = 5.toByte; - val R6 = 6.toByte; - val R7 = 7.toByte; - val R8 = 8.toByte; - val R9 = 9.toByte; + val Colls = new CollOverArrayBuilder - val SigmaDsl: SigmaDslBuilder = CSigmaDslBuilder - val noRegisters = collection[AnyValue]() - val noBytes = collection[Byte]() val noInputs = Array[Box]() val noOutputs = Array[Box]() val dummyPubkey: Array[Byte] = Array.fill(32)(0: Byte) - val dummyADDigest: Coll[Byte] = Colls.fromArray(Array.fill(33)(0: Byte)) val emptyAvlTree = new CAvlTree(AvlTreeData.dummy) val noHeaders = CSigmaDslBuilder.Colls.emptyColl[Header] val dummyPreHeader: PreHeader = null /** Create collection from array of items */ - def collection[T: RType](items: T*) = Colls.fromArray(items.toArray) - - /** Converts a map of registers to collection of registers. */ - def regs(m: Map[Byte, AnyValue]): Coll[AnyValue] = { - val res = new Array[AnyValue](10) - for ( (id, v) <- m ) { - assert(res(id) == null, s"register $id is defined more then once") - res(id) = v - } - Colls.fromArray(res) - } + def collection[T: RType](items: T*): Coll[T] = Colls.fromArray(items.toArray) /** Converts a map of context vars to collection of context vars. */ def contextVars(m: Map[Byte, AnyValue]): Coll[AnyValue] = { @@ -58,9 +33,7 @@ trait ContractsTestkit { Colls.fromArray(res) } - val AliceId = Array[Byte](1) // 0x0001 - - def newAliceBox(@nowarn id: Byte, value: Long): Box = { + def newAliceBox(value: Long): Box = { val ergoBox = testBox(value, ErgoTree.fromProposition(TrueSigmaProp), creationHeight = 0, additionalTokens = Seq(), additionalRegisters = Map()) @@ -90,8 +63,6 @@ trait ContractsTestkit { implicit class TestContextOps(ctx: CContext) { def withInputs(inputs: Box*) = ctx.copy(inputs = inputs.toArray.toColl) - def withOutputs(outputs: Box*) = ctx.copy(outputs = outputs.toArray.toColl) - def withVariables(vars: Map[Int, AnyValue]) = ctx.copy(vars = contextVars(vars.map { case (k, v) => (k.toByte, v) })) } diff --git a/interpreter/shared/src/test/scala/special/sigma/SigmaTestingData.scala b/interpreter/shared/src/test/scala/special/sigma/SigmaTestingData.scala index d33f09dd80..f113a484ef 100644 --- a/interpreter/shared/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/interpreter/shared/src/test/scala/special/sigma/SigmaTestingData.scala @@ -30,13 +30,6 @@ trait SigmaTestingData extends TestingCommons with ObjectGenerators { def Coll[T](items: T*)(implicit cT: RType[T]): Coll[T] = CSigmaDslBuilder.Colls.fromItems(items: _*) - /** Generator of random collection with `n` elements. */ - def collOfN[T: RType : Arbitrary](n: Int) - (implicit b: Buildable[T, Array[T]]): Gen[Coll[T]] = { - implicit val g: Gen[T] = Arbitrary.arbitrary[T] - containerOfN[Array, T](n, g).map(Colls.fromArray(_)) - } - val bytesGen: Gen[Array[Byte]] = for { len <- Gen.choose(0, 100) arr <- containerOfN[Array, Byte](len, Arbitrary.arbByte.arbitrary) @@ -54,63 +47,9 @@ trait SigmaTestingData extends TestingCommons with ObjectGenerators { res } - protected def sampleAvlProver = { - val keys = arrayOfN(100, keyCollGen).sample.get - val values = arrayOfN(100, bytesCollGen).sample.get - val (tree, prover) = createAvlTreeAndProver(keys.zip(values): _*) - (keys, values, tree, prover) - } - - protected def sampleAvlTree: AvlTree = { - val (_, _, _, avlProver) = sampleAvlProver - val digest = avlProver.digest.toColl - val tree = SigmaDsl.avlTree(AvlTreeFlags.ReadOnly.serializeToByte, digest, 32, None) - tree - } - val tokenId1: Digest32 = Blake2b256("id1") val tokenId2: Digest32 = Blake2b256("id2") - val header1: Header = CHeader(Blake2b256("Header.id").toColl, - 0, - Blake2b256("Header.parentId").toColl, - Blake2b256("ADProofsRoot").toColl, - sampleAvlTree, - Blake2b256("transactionsRoot").toColl, - timestamp = 0, - nBits = 0, - height = 0, - extensionRoot = Blake2b256("transactionsRoot").toColl, - minerPk = SigmaDsl.groupGenerator, - powOnetimePk = SigmaDsl.groupGenerator, - powNonce = Colls.fromArray(Array[Byte](0, 1, 2, 3, 4, 5, 6, 7)), - powDistance = SigmaDsl.BigInt(BigInt("1405498250268750867257727119510201256371618473728619086008183115260323").bigInteger), - votes = Colls.fromArray(Array[Byte](0, 1, 2)) - ) - val header2: Header = CHeader(Blake2b256("Header2.id").toColl, - 0, - header1.id, - Blake2b256("ADProofsRoot2").toColl, - sampleAvlTree, - Blake2b256("transactionsRoot2").toColl, - timestamp = 2, - nBits = 0, - height = 1, - extensionRoot = Blake2b256("transactionsRoot2").toColl, - minerPk = SigmaDsl.groupGenerator, - powOnetimePk = SigmaDsl.groupGenerator, - powNonce = Colls.fromArray(Array.fill(0.toByte)(8)), - powDistance = SigmaDsl.BigInt(BigInt("19306206489815517413186395405558417825367537880571815686937307203793939").bigInteger), - votes = Colls.fromArray(Array[Byte](0, 1, 0)) - ) - val headers = Colls.fromItems(header2, header1) - val preHeader: PreHeader = CPreHeader(0, - header2.id, - timestamp = 3, - nBits = 0, - height = 2, - minerPk = SigmaDsl.groupGenerator, - votes = Colls.emptyColl[Byte] - ) + object TestData { val BigIntZero: BigInt = CBigInt(new BigInteger("0", 16)) diff --git a/parsers/shared/src/test/scala/sigmastate/lang/LangTests.scala b/parsers/shared/src/test/scala/sigmastate/lang/LangTests.scala index c04f35ef71..498c3934bf 100644 --- a/parsers/shared/src/test/scala/sigmastate/lang/LangTests.scala +++ b/parsers/shared/src/test/scala/sigmastate/lang/LangTests.scala @@ -8,7 +8,6 @@ import sigma.ast._ import sigma.crypto.CryptoConstants import sigma.data.{CAnyValue, CSigmaDslBuilder, ProveDHTuple, ProveDlog, SigmaBoolean} import sigma.util.Extensions.BigIntegerOps -import sigmastate.eval._ import sigmastate.helpers.NegativeTesting import sigmastate.interpreter.Interpreter.ScriptEnv import sigma.ast.{Ident, MethodCallLike} diff --git a/sc/shared/src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala b/sc/shared/src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala index d4accabf3e..11cbaff739 100644 --- a/sc/shared/src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala +++ b/sc/shared/src/main/scala/org/ergoplatform/dsl/ContractSyntax.scala @@ -60,7 +60,7 @@ trait ContractSyntax { contract: SigmaContract => case _: Box => BoxRType case _: AvlTreeData => syntax.AvlTreeDataRType // TODO remove this RType case _: AvlTree => AvlTreeRType - case _: SigmaBoolean => syntax.SigmaBooleanRType // TODO remove this RType + case _: SigmaBoolean => SigmaBooleanRType // TODO remove this RType case _: SigmaProp => SigmaPropRType case _: Context => ContextRType case _ => diff --git a/sc/shared/src/main/scala/scalan/GraphIRReflection.scala b/sc/shared/src/main/scala/scalan/GraphIRReflection.scala index ee29924fb7..0eaba9d8a3 100644 --- a/sc/shared/src/main/scala/scalan/GraphIRReflection.scala +++ b/sc/shared/src/main/scala/scalan/GraphIRReflection.scala @@ -11,6 +11,10 @@ import special.wrappers.{OptionWrapSpec, RTypeWrapSpec} import wrappers.scalan.WRTypes /** Registrations of reflection metadata for graph-ir module (see README.md). + * Such metadata is only used on JS platform to support reflection-like interfaces of + * RClass, RMethod, RConstructor. These interfaces implemented on JVM using Java + * reflection. + * * For each class of this module that needs reflection metadata, * we register a class entry with the necessary information. * Only information that is needed at runtime is registered. diff --git a/sc/shared/src/main/scala/scalan/Library.scala b/sc/shared/src/main/scala/scalan/Library.scala index ee1ff80ad3..43f20813f0 100644 --- a/sc/shared/src/main/scala/scalan/Library.scala +++ b/sc/shared/src/main/scala/scalan/Library.scala @@ -107,7 +107,7 @@ trait Library extends Scalan override def invokeUnlifted(e: Elem[_], mc: MethodCall, dataEnv: DataEnv): Any = e match { case _: CollElem[_,_] => mc match { - case CollMethods.map(xs, f) => + case CollMethods.map(_, f) => val newMC = mc.copy(args = mc.args :+ f.elem.eRange)(mc.resultType, mc.isAdapterCall) super.invokeUnlifted(e, newMC, dataEnv) case _ => diff --git a/sc/shared/src/main/scala/scalan/MethodCalls.scala b/sc/shared/src/main/scala/scalan/MethodCalls.scala index af3c3201ef..14212df632 100644 --- a/sc/shared/src/main/scala/scalan/MethodCalls.scala +++ b/sc/shared/src/main/scala/scalan/MethodCalls.scala @@ -101,11 +101,6 @@ trait MethodCalls extends Base { self: Scalan => reifyObject(MethodCall(receiver, method, args, neverInvoke)(asElem[Any](resultElem), isAdapterCall)) } - /** Creates new NewObject node and returns its node ref. */ - def newObjEx[A](args: Any*)(implicit eA: Elem[A]): Ref[A] = { - reifyObject(NewObject[A](eA, args)) - } - @tailrec private def baseCause(e: Throwable): Throwable = e match { case e: ExceptionInInitializerError => baseCause(e.getCause) @@ -120,21 +115,6 @@ trait MethodCalls extends Base { self: Scalan => * point we know that the first RW set didn't triggered any rewrite. */ def rewriteNonInvokableMethodCall(@unused mc: MethodCall): Ref[_] = null - /** Create delegate instance suitable for method invocation. - * It is used when T is a class or a trait and the node referred by x doesn't conform to T. - * This method returns dynamically constructed instance, which conforms to T. - * Whenever a method of T is called on that instance, the call is intercepted and - * `DelegatedInterceptionHandler.invoke` method is called, then a new MethodCall can - * be constructed (which is befavior by default). - */ - protected def unrefDelegate[T <: AnyRef](x: Ref[T])(implicit ct: ClassTag[T]): T = { - val d = x.node - if (d.isInstanceOf[Const[_]]) - d.asInstanceOf[Const[T]@unchecked].x - else - !!!(s"Cannot do undefDelegate($x -> ${x.node})") - } - /** Generic helper to call the given method on the given receiver node. */ private[scalan] def invokeMethod[A](receiver: Sym, m: RMethod, args: Array[AnyRef], onInvokeSuccess: Any => A, @@ -148,9 +128,9 @@ trait MethodCalls extends Base { self: Scalan => } catch { case e: Exception => onInvokeException(baseCause(e)) } - } - else + } else { onInvokeImpossible + } } /** Method invocation enabler. diff --git a/sc/shared/src/main/scala/scalan/meta/SSymName.scala b/sc/shared/src/main/scala/scalan/meta/SSymName.scala index ea9b1546ba..b0f8dae6d2 100644 --- a/sc/shared/src/main/scala/scalan/meta/SSymName.scala +++ b/sc/shared/src/main/scala/scalan/meta/SSymName.scala @@ -6,16 +6,11 @@ case class ImportItem(packageName: String, importedNames: List[String]) case class SSymName(packageName: String, name: String) { import SSymName._ - def this(name: String) = this("", name) def mkFullName = fullNameString(packageName, name) - def isImportedBy(item: ImportItem): Boolean = { - if (packageName != item.packageName) return false - item.importedNames.contains(SSymName.ImportAllWildcard) || item.importedNames.contains(name) - } } object SSymName { - /** Wildcard character used to signify imporing all names from namespace */ + /** Wildcard character used to signify importing all names from namespace */ val ImportAllWildcard = "*" def fullNameString(packageName: String, name: String): String = if (packageName.isNullOrEmpty) name else s"$packageName.$name" diff --git a/sc/shared/src/main/scala/scalan/primitives/Functions.scala b/sc/shared/src/main/scala/scalan/primitives/Functions.scala index e5cd6f345e..9026461777 100644 --- a/sc/shared/src/main/scala/scalan/primitives/Functions.scala +++ b/sc/shared/src/main/scala/scalan/primitives/Functions.scala @@ -16,12 +16,6 @@ trait Functions extends Base with ProgramGraphs { self: Scalan => /** Apply given function symbol to the given argument symbol. * @return symbol representing result of function application */ final def apply(x: Ref[A]): Ref[B] = mkApply(f, x) - - /** Build new function which applies `f` and then `g`*/ - final def >>[C](g: Ref[B => C]): Ref[A => C] = compose(g, f) - - /** Build new function which applies `g` and then `f`*/ - final def <<[C](g: Ref[C => A]): Ref[C => B] = compose(f, g) } /** Global lambda equality mode used by default. It is used in `fun` and `fun2` lambda builders. @@ -332,7 +326,7 @@ trait Functions extends Base with ProgramGraphs { self: Scalan => val m = new java.util.HashMap[Sym, Sym](100) m.put(lam.x, s) val subst = new MapTransformer(m) - val t = DefaultMirror.mirrorSymbols(subst, NoRewriting, lam, body) + val t = DefaultMirror.mirrorSymbols(subst, NoRewriting, body) t(lam.y) } diff --git a/sc/shared/src/main/scala/scalan/primitives/Thunks.scala b/sc/shared/src/main/scala/scalan/primitives/Thunks.scala index ce51dc5638..f9f843664d 100644 --- a/sc/shared/src/main/scala/scalan/primitives/Thunks.scala +++ b/sc/shared/src/main/scala/scalan/primitives/Thunks.scala @@ -323,7 +323,7 @@ trait Thunks extends Functions { self: Scalan => */ def forceThunkDefByMirror[A](th: ThunkDef[A], subst: MapTransformer = MapTransformer.empty()): Ref[A] = { val body = th.scheduleIds - val t = DefaultMirror.mirrorSymbols(subst, NoRewriting, th, body) + val t = DefaultMirror.mirrorSymbols(subst, NoRewriting, body) t(th.root) } diff --git a/sc/shared/src/main/scala/scalan/staged/Transforming.scala b/sc/shared/src/main/scala/scalan/staged/Transforming.scala index 045340e503..a64b998ff6 100644 --- a/sc/shared/src/main/scala/scalan/staged/Transforming.scala +++ b/sc/shared/src/main/scala/scalan/staged/Transforming.scala @@ -47,9 +47,6 @@ trait Transforming { self: Scalan => constantPropagation: Boolean = true, /** Used in SlicingPass */ shouldSlice: Boolean = false) - { - def withConstantPropagation(value: Boolean) = this.copy(constantPropagation = value) - } /** Default pass to be used when IR is used without special compiler configuration. */ class DefaultPass(val name: String, override val config: PassConfig = PassConfig()) extends Pass @@ -65,10 +62,6 @@ trait Transforming { self: Scalan => def beginPass(pass: Pass): Unit = { _currentPass = pass } - /** Called to let this IR context to finalized the given pass. */ - def endPass(pass: Pass): Unit = { - _currentPass = Pass.defaultPass - } /** Concrete and default implementation of Transformer using underlying HashMap. * HOTSPOT: don't beatify the code */ @@ -152,7 +145,7 @@ trait Transforming { self: Scalan => protected def mirrorElem(node: Sym): Elem[_] = node.elem // every mirrorXXX method should return a pair (t + (v -> v1), v1) - protected def mirrorVar[A](t: Transformer, rewriter: Rewriter, v: Ref[A]): Transformer = { + protected def mirrorVar[A](t: Transformer, v: Ref[A]): Transformer = { val newVar = variable(Lazy(mirrorElem(v))) t + (v, newVar) } @@ -173,7 +166,7 @@ trait Transforming { self: Scalan => protected def mirrorLambda[A, B](t: Transformer, rewriter: Rewriter, node: Ref[A => B], lam: Lambda[A, B]): Transformer = { var tRes: Transformer = t - val t1 = mirrorNode(t, rewriter, lam, lam.x) + val t1 = mirrorNode(t, rewriter, lam.x) // original root val originalRoot = lam.y @@ -190,7 +183,7 @@ trait Transforming { self: Scalan => // lambdaStack = newLambdaCandidate :: lambdaStack val newRoot = { // reifyEffects block val schedule = lam.scheduleIds - val t2 = mirrorSymbols(t1, rewriter, lam, schedule) + val t2 = mirrorSymbols(t1, rewriter, schedule) tRes = t2 tRes(originalRoot) // this will be a new root } @@ -214,7 +207,7 @@ trait Transforming { self: Scalan => val newScope = thunkStack.beginScope(newThunkSym) val schedule = thunk.scheduleIds - val t1 = mirrorSymbols(t, rewriter, thunk, schedule) + val t1 = mirrorSymbols(t, rewriter, schedule) thunkStack.endScope() val newRoot = t1(thunk.root) @@ -230,12 +223,12 @@ trait Transforming { self: Scalan => protected def isMirrored(t: Transformer, node: Sym): Boolean = t.isDefinedAt(node) - def mirrorNode(t: Transformer, rewriter: Rewriter, g: AstGraph, node: Sym): Transformer = { + def mirrorNode(t: Transformer, rewriter: Rewriter, node: Sym): Transformer = { if (isMirrored(t, node)) t else { node.node match { - case v: Variable[_] => - mirrorVar(t, rewriter, node) + case _: Variable[_] => + mirrorVar(t, node) case lam: Lambda[a, b] => mirrorLambda(t, rewriter, node.asInstanceOf[Ref[a => b]], lam) case th: ThunkDef[a] => @@ -247,12 +240,12 @@ trait Transforming { self: Scalan => } /** HOTSPOT: */ - def mirrorSymbols(t0: Transformer, rewriter: Rewriter, g: AstGraph, nodes: DBuffer[Int]) = { + def mirrorSymbols(t0: Transformer, rewriter: Rewriter, nodes: DBuffer[Int]): Transformer = { var t: Transformer = t0 cfor(0)(_ < nodes.length, _ + 1) { i => val n = nodes(i) val s = getSym(n) - t = mirrorNode(t, rewriter, g, s) + t = mirrorNode(t, rewriter, s) } t } diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index 9c9fa5ffe1..5ddcdfa946 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala @@ -52,10 +52,6 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => this.keepOriginalFunc = false // original lambda of Lambda node contains invocations of evalNode and we don't want that this.useAlphaEquality = false - /** Whether to create CostOf nodes or substutute costs from CostTable as constants in the graph. - * true - substitute; false - create CostOf nodes */ - var substFromCostTable: Boolean = true - /** Whether to save calcF and costF graphs in the file given by ScriptNameProp environment variable */ var saveGraphsInFile: Boolean = false @@ -380,8 +376,6 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => case _ => error(s"Cannot find BinOp for opcode newOpCode(${opCode.toUByte - LastConstantCode}) and type $eA") } - import sigmastate._ - protected implicit def groupElementToECPoint(g: sigma.GroupElement): EcPointType = CSigmaDslBuilder.toECPoint(g).asInstanceOf[EcPointType] def error(msg: String) = throw new GraphBuildingException(msg, None) @@ -436,7 +430,7 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => error(s"Don't know how to buildNode($node)", node.sourceContext.toOption) val res: Ref[Any] = node match { - case c @ Constant(v, tpe) => v match { + case Constant(v, tpe) => v match { case p: SSigmaProp => assert(tpe == SSigmaProp) val resV = liftConst(p) @@ -887,7 +881,7 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => f } - case l @ FuncValue(Seq((n, argTpe)), body) => + case FuncValue(Seq((n, argTpe)), body) => val eArg = stypeToElem(argTpe).asInstanceOf[Elem[Any]] val f = fun { x: Ref[Any] => buildNode(ctx, env + (n -> x), body) diff --git a/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala b/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala index b84098f2e7..597711d458 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala @@ -1,65 +1,25 @@ package sigmastate.eval import sigma.ast.TransformingSigmaBuilder -import sigma.data.CSigmaDslBuilder - -import java.util.concurrent.locks.ReentrantLock -import scala.util.Try /** Main interface of graph IR context which contain both GraphBuilding and TreeBuilding * methods. * It is not used in v5.0 interpreter and thus not part of consensus. * - * @see RuntimeIRContext, CompiletimeIRContext + * Used in ErgoScript compiler only. + * + * @see CompiletimeIRContext */ trait IRContext extends TreeBuilding with GraphBuilding { - import SigmaProp._ - - private val SigmaM = SigmaPropMethods - override val builder = TransformingSigmaBuilder - /** Can be used to synchronize access to this IR object from multiple threads. */ - val lock = new ReentrantLock() - /** Pass configuration which is used to turn-off constant propagation. + * USED IN TESTS ONLY. * @see `beginPass(noCostPropagationPass)` */ lazy val noConstPropagationPass = new DefaultPass( "noCostPropagationPass", Pass.defaultPassConfig.copy(constantPropagation = false)) - - /** The value of Global ErgoTree operation */ - val sigmaDslBuilderValue = CSigmaDslBuilder - - /** Finds SigmaProp.isProven method calls in the given Lambda `f` */ - def findIsProven[T](f: Ref[Context => T]): Option[Sym] = { - val Def(Lambda(lam,_,_,_)) = f - val s = lam.flatSchedule.find(sym => sym.node match { - case SigmaM.isValid(_) => true - case _ => false - }) - s - } - - /** Checks that if SigmaProp.isProven method calls exists in the given Lambda's schedule, - * then it is the last operation. */ - def verifyIsProven[T](f: Ref[Context => T]): Try[Unit] = { - val isProvenOpt = findIsProven(f) - Try { - isProvenOpt match { - case Some(s) => - if (f.getLambda.y != s) !!!(s"Sigma.isProven found in none-root position", s) - case None => - } - } - } -} - -/** IR context to be used by blockchain nodes to validate transactions. */ -class RuntimeIRContext extends IRContext { } /** IR context to be used by script development tools to compile ErgoScript into ErgoTree bytecode. */ -class CompiletimeIRContext extends IRContext { -} - +class CompiletimeIRContext extends IRContext diff --git a/sc/shared/src/main/scala/sigmastate/eval/SigmaLibrary.scala b/sc/shared/src/main/scala/sigmastate/eval/SigmaLibrary.scala index be17179cbf..7745873620 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/SigmaLibrary.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/SigmaLibrary.scala @@ -10,7 +10,7 @@ trait SigmaLibrary extends Library { import WRType._ - implicit lazy val wRTypeAnyElement = wRTypeElement(AnyElement) + implicit lazy val wRTypeAnyElement: Elem[WRType[Any]] = wRTypeElement(AnyElement) /** During compilation represent a global value Global, see also SGlobal type. */ def sigmaDslBuilder: Ref[SigmaDslBuilder] diff --git a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala index 26bc33956f..27f659c1ed 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -161,7 +161,7 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => case _ if env.contains(s) => val (id, tpe) = env(s) ValUse(id, tpe) // recursion base - case Def(Lambda(lam, _, x, y)) => + case Def(Lambda(lam, _, x, _)) => val varId = defId + 1 // arguments are treated as ValDefs and occupy id space val env1 = env + (x -> (varId, elemToSType(x.elem))) val block = processAstGraph(ctx, mainG, env1, lam, varId + 1, constantsProcessing) @@ -170,7 +170,7 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => case Def(Apply(fSym, xSym, _)) => val Seq(f, x) = Seq(fSym, xSym).map(recurse) builder.mkApply(f, Array(x)) - case Def(th @ ThunkDef(root, _)) => + case Def(th @ ThunkDef(_, _)) => val block = processAstGraph(ctx, mainG, env, th, defId, constantsProcessing) block case Def(Const(x)) => @@ -449,7 +449,7 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => (valdefs.toArray[BlockItem], rhs) match { // simple optimization to avoid producing block sub-expressions like: // `{ val idNew = id; idNew }` which this rules rewrites to just `id` - case (Array(ValDef(idNew, _, source @ ValUse(id, tpe))), ValUse(idUse, tpeUse)) + case (Array(ValDef(idNew, _, source @ ValUse(_, tpe))), ValUse(idUse, tpeUse)) if idUse == idNew && tpeUse == tpe => source case (items, _) => BlockValue(items, rhs) diff --git a/sc/shared/src/main/scala/sigmastate/lang/SigmaBinder.scala b/sc/shared/src/main/scala/sigmastate/lang/SigmaBinder.scala index f93e31703d..82aaea7e30 100644 --- a/sc/shared/src/main/scala/sigmastate/lang/SigmaBinder.scala +++ b/sc/shared/src/main/scala/sigmastate/lang/SigmaBinder.scala @@ -1,7 +1,6 @@ package sigmastate.lang import org.ergoplatform.ErgoAddressEncoder.NetworkPrefix -import org.ergoplatform._ import sigma.ast.NoType import sigma.data.Nullable import sigma.kiama.rewriting.CallbackRewriter diff --git a/sc/shared/src/main/scala/special/collection/CollsUnit.scala b/sc/shared/src/main/scala/special/collection/CollsUnit.scala index 02e62aeb4d..90f0dca99e 100644 --- a/sc/shared/src/main/scala/special/collection/CollsUnit.scala +++ b/sc/shared/src/main/scala/special/collection/CollsUnit.scala @@ -9,9 +9,6 @@ package sigma { * for details. */ trait Colls extends Base { self: Library => - import Coll._; - import CollBuilder._; - import WOption._; trait Coll[A] extends Def[Coll[A]] { implicit def eA: Elem[A]; def length: Ref[Int]; @@ -37,7 +34,5 @@ package sigma { def xor(left: Ref[Coll[Byte]], right: Ref[Coll[Byte]]): Ref[Coll[Byte]]; def replicate[T](n: Ref[Int], v: Ref[T]): Ref[Coll[T]]; }; - trait CollCompanion; - trait CollBuilderCompanion } } \ No newline at end of file diff --git a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala index 8da36ce6cf..70fb35c329 100644 --- a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -22,19 +22,16 @@ import BigInt._ import Box._ import Coll._ import CollBuilder._ -import Context._ import GroupElement._ import Header._ import PreHeader._ -import SigmaDslBuilder._ import SigmaProp._ import WOption._ -import WRType._ + object BigInt extends EntityObject("BigInt") { // entityConst: single const for each entity import Liftables._ - import scala.reflect.{ClassTag, classTag} type SBigInt = sigma.BigInt case class BigIntConst( constValue: SBigInt @@ -1918,7 +1915,6 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { } override def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]]): Ref[Coll[Byte]] = { - implicit val eT = newValues.eA asRep[Coll[Byte]](mkMethodCall(self, SigmaDslBuilderClass.getMethod("substConstants", classOf[Sym], classOf[Sym], classOf[Sym]), Array[AnyRef](scriptBytes, positions, newValues), @@ -2078,7 +2074,6 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { } def substConstants[T](scriptBytes: Ref[Coll[Byte]], positions: Ref[Coll[Int]], newValues: Ref[Coll[T]]): Ref[Coll[Byte]] = { - implicit val eT = newValues.eA asRep[Coll[Byte]](mkMethodCall(source, SigmaDslBuilderClass.getMethod("substConstants", classOf[Sym], classOf[Sym], classOf[Sym]), Array[AnyRef](scriptBytes, positions, newValues), @@ -2281,16 +2276,6 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[GroupElement], Ref[GroupElement], Ref[GroupElement], Ref[GroupElement])] = unapply(exp.node) } - object groupGenerator { - def unapply(d: Def[_]): Nullable[Ref[SigmaDslBuilder]] = d match { - case MethodCall(receiver, method, _, _) if method.getName == "groupGenerator" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => - val res = receiver - Nullable(res).asInstanceOf[Nullable[Ref[SigmaDslBuilder]]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[Ref[SigmaDslBuilder]] = unapply(exp.node) - } - object substConstants { def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Ref[Coll[Int]], Ref[Coll[T]]) forSome {type T}] = d match { case MethodCall(receiver, method, args, _) if method.getName == "substConstants" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => diff --git a/sc/shared/src/test/scala/scalan/LibraryTests.scala b/sc/shared/src/test/scala/scalan/LibraryTests.scala index e082e9154d..d095a2f20a 100644 --- a/sc/shared/src/test/scala/scalan/LibraryTests.scala +++ b/sc/shared/src/test/scala/scalan/LibraryTests.scala @@ -8,7 +8,7 @@ class Benchmark[T <: Scalan](createContext: => T) { def run() = { val (ctx, total) = measureTime { var ctx = createContext - measure(10000, okShowIterTime = printDebugInfo, okShowTotalTime = printDebugInfo) { i => + measure(10000, okShowIterTime = printDebugInfo, okShowTotalTime = printDebugInfo) { _ => ctx = createContext } ctx diff --git a/sc/shared/src/test/scala/sigma/SigmaDslStaginTests.scala b/sc/shared/src/test/scala/sigma/SigmaDslStaginTests.scala index 5ac9b80889..91178b2b67 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslStaginTests.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslStaginTests.scala @@ -28,8 +28,8 @@ class SigmaDslStaginTests extends BaseCtxTests with ErgoScriptTestkit with BaseL type RContext = cake.Context type RBox = cake.Box type RSigmaProp = cake.SigmaProp - val boxA1 = newAliceBox(1, 100) - val boxA2 = newAliceBox(2, 200) + val boxA1 = newAliceBox(100) + val boxA2 = newAliceBox(200) val ctx: SContext = newContext(10, boxA1, VersionContext.MaxSupportedScriptVersion, VersionContext.MaxSupportedScriptVersion) .withInputs(boxA2) .withVariables(Map(1 -> toAnyValue(30), 2 -> toAnyValue(40))) diff --git a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala index 0b3e275985..b0b6273fad 100644 --- a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala @@ -332,7 +332,6 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { ), true) }, - { // SBigInt inherit methods from SNumericType.methods // however they are not resolvable via SBigInt.typeId import SNumericTypeMethods._ diff --git a/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index bca2d0e638..c8b9f06399 100644 --- a/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -29,7 +29,7 @@ class SoftForkabilitySpecification extends SigmaTestingData with CompilerTestingCommons with BeforeAndAfterAll { - implicit lazy val IR: TestingIRContext = new TestingIRContext + val IR: TestingIRContext = new TestingIRContext lazy val prover = new ErgoLikeTestProvingInterpreter() lazy val verifier = new ErgoLikeTestInterpreter val deadline = 100 @@ -38,7 +38,7 @@ class SoftForkabilitySpecification extends SigmaTestingData lazy val booleanPropV1 = compile(emptyEnv + ("deadline" -> deadline), """{ | HEIGHT > deadline && OUTPUTS.size == 1 - |}""".stripMargin).asBoolValue + |}""".stripMargin)(IR).asBoolValue // cast Boolean typed prop to SigmaProp (which is invalid) // ErgoTree v0 lazy val invalidPropV1: ErgoTree = diff --git a/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index fe5a678679..446f1972a7 100644 --- a/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -22,15 +22,12 @@ import scala.util.Random class TestingInterpreterSpecification extends CompilerTestingCommons with CompilerCrossVersionProps with BeforeAndAfterAll { - implicit lazy val IR: TestingIRContext = new TestingIRContext - lazy val prover = new ErgoLikeTestProvingInterpreter() { - } + val IR: TestingIRContext = new TestingIRContext - lazy val verifier = new ErgoLikeTestInterpreter { - } + lazy val prover = new ErgoLikeTestProvingInterpreter() - implicit val soundness: Int = CryptoConstants.soundnessBits + lazy val verifier = new ErgoLikeTestInterpreter def testingContext(h: Int) = ErgoLikeContextTesting(h, @@ -128,7 +125,7 @@ class TestingInterpreterSpecification extends CompilerTestingCommons "box1" -> testBox(10, TrueTree, 0, Seq(), Map( reg1 -> IntArrayConstant(Array[Int](1, 2, 3)), reg2 -> BoolArrayConstant(Array[Boolean](true, false, true))))) - val prop = mkTestErgoTree(compile(env, code).asBoolValue.toSigmaProp) + val prop = mkTestErgoTree(compile(env, code)(IR).asBoolValue.toSigmaProp) val challenge = Array.fill(32)(Random.nextInt(100).toByte) val proof1 = prover.prove(prop, ctx, challenge).get.proof verifier.verify(Interpreter.emptyEnv, prop, ctx, proof1, challenge) diff --git a/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala b/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala index abbed09992..a10a717d2f 100644 --- a/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala +++ b/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala @@ -21,7 +21,7 @@ import sigmastate.CompilerTestsBase import sigma.{ContractsTestkit, Context => DContext} import scala.annotation.unused -import scala.util.Success +import scala.util.{Success, Try} trait ErgoScriptTestkit extends ContractsTestkit with LangTests with ValidationSpecification with CompilerTestsBase { self: BaseCtxTests => @@ -54,9 +54,8 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests ergoCtx } - - lazy val boxA1 = newAliceBox(1, 100) - lazy val boxA2 = newAliceBox(2, 200) + lazy val boxA1 = newAliceBox(100) + lazy val boxA2 = newAliceBox(200) lazy val n1Sym = liftConst(n1) @@ -147,6 +146,31 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests res } + private val SigmaM = SigmaProp.SigmaPropMethods + + /** Finds SigmaProp.isProven method calls in the given Lambda `f` */ + private def findIsProven[T](f: Ref[Context => T]): Option[Sym] = { + val Def(Lambda(lam,_,_,_)) = f + val s = lam.flatSchedule.find(sym => sym.node match { + case SigmaM.isValid(_) => true + case _ => false + }) + s + } + + /** Checks that if SigmaProp.isProven method calls exists in the given Lambda's schedule, + * then it is the last operation. */ + private def verifyIsProven[T](f: Ref[Context => T]): Try[Unit] = { + val isProvenOpt = findIsProven(f) + Try { + isProvenOpt match { + case Some(s) => + if (f.getLambda.y != s) !!!(s"Sigma.isProven found in none-root position", s) + case None => + } + } + } + def doReduce(): Unit = { val res = doCosting verifyIsProven(res.compiledGraph) shouldBe Success(()) @@ -183,13 +207,6 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests } } - def Case(env: ScriptEnv, name: String, script: String, ctx: ErgoLikeContext, - calc: Ref[Context] => Ref[Any], - tree: SValue, - result: Result) = - EsTestCase(name, env, Code(script), Option(ctx), None, - Option(calc), Option(tree), result) - def reduce(env: ScriptEnv, name: String, script: String, ergoCtx: ErgoLikeContext, expectedResult: Any): Unit = { val tcase = EsTestCase(name, env, Code(script), Some(ergoCtx), expectedResult = Result(expectedResult)) tcase.doReduce() diff --git a/sc/shared/src/test/scala/sigmastate/eval/EvaluationTest.scala b/sc/shared/src/test/scala/sigmastate/eval/EvaluationTest.scala index 5fcbd0f220..f9a7edf0cb 100644 --- a/sc/shared/src/test/scala/sigmastate/eval/EvaluationTest.scala +++ b/sc/shared/src/test/scala/sigmastate/eval/EvaluationTest.scala @@ -81,24 +81,6 @@ class EvaluationTest extends BaseCtxTests | f(SELF) || g(SELF.R5[Coll[Int]].get) | }""".stripMargin, ctx, true) } - - test("Measure IRContext creation speed") { - var ctx: RuntimeIRContext = new RuntimeIRContext - measure(100, okShowIterTime = printDebugInfo, okShowTotalTime = printDebugInfo) { i => - ctx = new RuntimeIRContext - } - printDebug(s"Def count: ${ctx.defCount}") - /* - Iter 0: 4 ms - ... - Iter 96: 2 ms - Iter 97: 1 ms - Iter 98: 2 ms - Iter 99: 2 ms - Total time: 244 ms - Def count: 20 - */ - } test("SubstConst") { def script(pk: ProveDlog): SigmaPropValue = diff --git a/sc/shared/src/test/scala/sigmastate/eval/MeasureIRContext.scala b/sc/shared/src/test/scala/sigmastate/eval/MeasureIRContext.scala deleted file mode 100644 index 9f88588cc9..0000000000 --- a/sc/shared/src/test/scala/sigmastate/eval/MeasureIRContext.scala +++ /dev/null @@ -1,36 +0,0 @@ -package sigmastate.eval - -import scalan.{BaseCtxTests, Benchmark} -import sigma.util.BenchmarkUtil.measure - -object MeasureIRContext extends App { - var ctx: RuntimeIRContext = null - measure(1, false) { i => - ctx = new RuntimeIRContext - } - measure(10000, false) { i => - ctx = new RuntimeIRContext - } - print(s"Def count: ${ctx.defCount}") - /* - Total time: 2485 ms - Total time: 2714 ms - Def count: 20 - */ -} - -class SigmaLibraryTests extends BaseCtxTests { - - test("Benchmark SigmaLibrary creation time") { - new Benchmark(new RuntimeIRContext).run() - } -} - -object MeasureSigmaLibraryCreate extends App { - new Benchmark(new RuntimeIRContext).run() - /* - Total time: 12932 ms - Def count: 20, total: 15774 msec - */ -} - diff --git a/sc/shared/src/test/scala/sigmastate/helpers/CompilerTestingCommons.scala b/sc/shared/src/test/scala/sigmastate/helpers/CompilerTestingCommons.scala index 332ee902a2..6c3708b782 100644 --- a/sc/shared/src/test/scala/sigmastate/helpers/CompilerTestingCommons.scala +++ b/sc/shared/src/test/scala/sigmastate/helpers/CompilerTestingCommons.scala @@ -29,8 +29,7 @@ trait CompilerTestingCommons extends TestingCommons with TestUtils with TestContexts with ValidationSpecification with CompilerTestsBase { - class TestingIRContext extends TestContext with IRContext { - } + class TestingIRContext extends TestContext with IRContext case class CompiledFunc[A,B] (script: String, bindings: Seq[VarBinding], expr: SValue, compiledTree: SValue, func: A => (B, CostDetails)) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 346ad69e1a..79701d6e07 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -5,7 +5,7 @@ import org.ergoplatform._ import sigma.Extensions.ArrayOps import sigma.ast.SCollection.SByteArray import sigma.ast.SType.AnyOps -import sigma.data.{AvlTreeData, CAnyValue} +import sigma.data.{AvlTreeData, CAnyValue, CSigmaDslBuilder} import sigma.util.StringUtil._ import sigma.ast._ import sigma.ast.syntax._ @@ -339,7 +339,7 @@ class BasicOpsSpecification extends CompilerTestingCommons }) val dataVar = (lastExtVar + 1).toByte - val Colls = IR.sigmaDslBuilderValue.Colls + val Colls = CSigmaDslBuilder.Colls implicit val eAny = sigma.AnyType val data = Colls.fromItems((Array[Byte](1,2,3).toColl, 10L)) val env1 = env + ("dataVar" -> CAnyValue(dataVar)) diff --git a/sdk/shared/src/main/scala/org/ergoplatform/sdk/Extensions.scala b/sdk/shared/src/main/scala/org/ergoplatform/sdk/Extensions.scala index c8fb2e57f8..320aae5919 100644 --- a/sdk/shared/src/main/scala/org/ergoplatform/sdk/Extensions.scala +++ b/sdk/shared/src/main/scala/org/ergoplatform/sdk/Extensions.scala @@ -13,29 +13,6 @@ import scala.reflect.ClassTag object Extensions { - implicit class GenIterableOps[A, Source[X] <: GenIterable[X]](val xs: Source[A]) extends AnyVal { - - /** Apply m for each element of this collection, group by key and reduce each group - * using r. - * Note, the ordering of the resulting keys is deterministic and the keys appear in - * the order they first produced by `map`. - * - * @returns one item for each group in a new collection of (K,V) pairs. */ - def mapReduce[K, V](map: A => (K, V))(reduce: (V, V) => V) - (implicit cbf: BuildFrom[Source[A], (K, V), Source[(K, V)]]): Source[(K, V)] = { - val result = scala.collection.mutable.LinkedHashMap.empty[K, V] - xs.foreach { x => - val (key, value) = map(x) - val reduced = if (result.contains(key)) reduce(result(key), value) else value - result.update(key, reduced) - } - - val b = cbf.newBuilder(xs) - for ( kv <- result ) b += kv - b.result() - } - } - implicit class CollOps[A](val coll: Coll[A]) extends AnyVal { /** Partitions this $coll in two $colls according to a predicate. @@ -205,7 +182,4 @@ object Extensions { } } - implicit class DoubleOps(val i: Double) extends AnyVal { - def erg: Long = (i * 1000000000L).toLong - } } diff --git a/sdk/shared/src/test/scala/org/ergoplatform/sdk/ExtensionsSpec.scala b/sdk/shared/src/test/scala/org/ergoplatform/sdk/ExtensionsSpec.scala index 98f61331bb..1f3c8d9064 100644 --- a/sdk/shared/src/test/scala/org/ergoplatform/sdk/ExtensionsSpec.scala +++ b/sdk/shared/src/test/scala/org/ergoplatform/sdk/ExtensionsSpec.scala @@ -4,7 +4,8 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.propspec.AnyPropSpec import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import sigma.{Coll, CollGens} -import org.ergoplatform.sdk.Extensions.{CollBuilderOps, CollOps, GenIterableOps, PairCollOps} +import org.ergoplatform.sdk.Extensions.{CollBuilderOps, CollOps, PairCollOps} +import sigma.Extensions.ArrayOps import sigma.data.{CSigmaDslBuilder, RType} class ExtensionsSpec extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with CollGens { @@ -13,10 +14,6 @@ class ExtensionsSpec extends AnyPropSpec with ScalaCheckPropertyChecks with Matc val items: Iterable[(Int, String)] = Array((1, "a"), (2, "b"), (1, "c")) - property("Traversable.mapReduce") { - val res = items.mapReduce(p => (p._1, p._2))((v1, v2) => v1 + v2) - assertResult(List((1, "ac"), (2, "b")))(res) - } property("Coll.partition") { forAll(collGen) { col: Coll[Int] => @@ -28,14 +25,14 @@ class ExtensionsSpec extends AnyPropSpec with ScalaCheckPropertyChecks with Matc } property("Coll.mapReduce") { - def m(x: Int) = (math.abs(x) % 10, x) + def m(x: Int): (Int, Int) = (math.abs(x) % 10, x) forAll(collGen) { col => val res = col.mapReduce(m, plusF) val (ks, vs) = builder.unzip(res) vs.toArray.sum shouldBe col.toArray.sum ks.length <= 10 shouldBe true - res.toArray shouldBe col.toArray.toIterable.mapReduce(m)(plus).toArray + res.toArray shouldBe col.toArray.toColl.mapReduce[Int, Int](m, plusF).toArray } } From 98e2756cb363462b6fd459a6789a9a274e120898 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Mon, 6 May 2024 14:07:44 +0300 Subject: [PATCH 08/25] moving failing test from #612 to here --- .../sigmastate/utxo/BasicOpsSpecification.scala | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 79701d6e07..9f8d3c2f79 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -19,6 +19,7 @@ import sigmastate.interpreter.Interpreter._ import sigma.ast.Apply import sigma.eval.EvalSettings import sigma.exceptions.InvalidType +import sigma.serialization.ValueSerializer import sigmastate.utils.Helpers._ import java.math.BigInteger @@ -157,6 +158,17 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } + property("executeFromVar") { + val script = GT(Height, IntConstant(1)).toSigmaProp + val scriptBytes = ValueSerializer.serialize(script) + val customExt = Seq(21.toByte -> ByteArrayConstant(scriptBytes)) + test("executeFromVar", env, customExt, + "executeFromVar[SigmaProp](21)", + null, + true + ) + } + property("Relation operations") { test("R1", env, ext, "{ allOf(Coll(getVar[Boolean](trueVar).get, true, true)) }", From 624558fdec9a82240e208a7ce2f55c28c4d51d58 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 7 May 2024 17:16:25 +0300 Subject: [PATCH 09/25] executeFromVar tests are passing --- .../src/main/scala/sigma/SigmaDsl.scala | 2 ++ .../main/scala/sigma/ast/SigmaPredef.scala | 33 +++++++++---------- .../scala/sigma/data/CSigmaDslBuilder.scala | 17 ++++++++-- .../sigmastate/interpreter/Interpreter.scala | 2 +- sc/shared/src/main/scala/scalan/Base.scala | 2 +- .../scala/sigmastate/eval/GraphBuilding.scala | 6 ++++ .../scala/special/sigma/SigmaDslUnit.scala | 1 + .../special/sigma/impl/SigmaDslImpl.scala | 14 ++++++++ .../test/scala/sigma/SigmaDslTesting.scala | 2 +- .../utxo/BasicOpsSpecification.scala | 3 +- .../ExecuteFromExamplesSpecification.scala | 5 +-- 11 files changed, 59 insertions(+), 28 deletions(-) diff --git a/core/shared/src/main/scala/sigma/SigmaDsl.scala b/core/shared/src/main/scala/sigma/SigmaDsl.scala index df2b419273..29142a624c 100644 --- a/core/shared/src/main/scala/sigma/SigmaDsl.scala +++ b/core/shared/src/main/scala/sigma/SigmaDsl.scala @@ -729,5 +729,7 @@ trait SigmaDslBuilder { /** Returns a byte-wise XOR of the two collections of bytes. */ def xor(l: Coll[Byte], r: Coll[Byte]): Coll[Byte] + + def deserialize[T](bytes: Coll[Byte])(implicit cT: RType[T]): T } diff --git a/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala b/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala index 631f7f2d75..716b167e2b 100644 --- a/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala +++ b/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala @@ -136,17 +136,6 @@ object SigmaPredef { Seq(ArgInfo("condition", "boolean value to embed in SigmaProp value"))) ) - val GetVarFunc = PredefinedFunc("getVar", - Lambda(Array(paramT), Array("varId" -> SByte), SOption(tT), None), - PredefFuncInfo( - { case (Ident(_, SFunc(_, SOption(rtpe), _)), Seq(id: Constant[SNumericType]@unchecked)) => - mkGetVar(SByte.downcast(id.value.asInstanceOf[AnyVal]), rtpe) - }), - OperationInfo(GetVar, - "Get context variable with given \\lst{varId} and type.", - Seq(ArgInfo("varId", "\\lst{Byte} identifier of context variable"))) - ) - def PKFunc(networkPrefix: NetworkPrefix) = PredefinedFunc("PK", Lambda(Array("input" -> SString), SSigmaProp, None), PredefFuncInfo( @@ -366,13 +355,23 @@ object SigmaPredef { ArgInfo("newValues", "new values to be injected into the corresponding positions in ErgoTree.constants array"))) ) + val GetVarFunc = PredefinedFunc("getVar", + Lambda(Array(paramT), Array("varId" -> SByte), SOption(tT), None), + PredefFuncInfo( + { case (Ident(_, SFunc(_, SOption(rtpe), _)), Seq(id: Constant[SNumericType]@unchecked)) => + mkGetVar(SByte.downcast(id.value.asInstanceOf[AnyVal]), rtpe) + }), + OperationInfo(GetVar, + "Get context variable with given \\lst{varId} and type.", + Seq(ArgInfo("varId", "\\lst{Byte} identifier of context variable"))) + ) + val ExecuteFromVarFunc = PredefinedFunc("executeFromVar", - Lambda( - Seq(paramT), - Array("id" -> SByte), - tT, None - ), - PredefFuncInfo(undefined), + Lambda(Array(paramT), Array("id" -> SByte), tT, None), + PredefFuncInfo( + { case (Ident(_, SFunc(_, rtpe, _)), Seq(id: Constant[SNumericType]@unchecked)) => + mkDeserializeContext(SByte.downcast(id.value.asInstanceOf[AnyVal]), rtpe) + }), OperationInfo(DeserializeContext, """Extracts context variable as \lst{Coll[Byte]}, deserializes it to script | and then executes this script in the current context. diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index 3938feacd3..cc5eb3e7d6 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -5,10 +5,12 @@ import org.ergoplatform.ErgoBox import org.ergoplatform.validation.ValidationRules import scorex.crypto.hash.{Blake2b256, Sha256} import scorex.utils.Longs -import sigma.ast.{AtLeast, SubstConstants} +import sigma.Evaluation.stypeToRType +import sigma.ast.{AtLeast, EvaluatedValue, SType, SubstConstants, Value} import sigma.crypto.{CryptoConstants, EcPointType, Ecp} -import sigma.eval.Extensions.EvalCollOps -import sigma.serialization.{GroupElementSerializer, SigmaSerializer} +import sigma.eval.Extensions.{EvalCollOps, toAnyValue} +import sigma.exceptions.InvalidType +import sigma.serialization.{GroupElementSerializer, SigmaSerializer, ValueSerializer} import sigma.util.Extensions.BigIntegerOps import sigma.validation.SigmaValidationSettings import sigma.{AvlTree, BigInt, Box, Coll, CollBuilder, GroupElement, SigmaDslBuilder, SigmaProp, VersionContext} @@ -200,6 +202,15 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => val p = GroupElementSerializer.parse(r) this.GroupElement(p) } + + def deserialize[T](bytes: Coll[Byte])(implicit cT: RType[T]): T = { + val v = ValueSerializer.deserialize(bytes.toArray) + if(stypeToRType(v.tpe) == cT) { + v.asInstanceOf[EvaluatedValue[_]].value.asInstanceOf[T] + } else { + throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: $cT") + } + } } /** Default singleton instance of Global object, which implements global ErgoTree functions. */ diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala index 9a1ab11f0e..8e8da22462 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -126,7 +126,7 @@ trait Interpreter { case _ => None } - /** Extracts proposition for ErgoTree handing soft-fork condition. + /** Extracts proposition for ErgoTree handling soft-fork condition. * @note soft-fork handler */ protected def propositionFromErgoTree(ergoTree: ErgoTree, context: CTX): SigmaPropValue = { val validationSettings = context.validationSettings diff --git a/sc/shared/src/main/scala/scalan/Base.scala b/sc/shared/src/main/scala/scalan/Base.scala index cc29af45b9..dd4079054f 100644 --- a/sc/shared/src/main/scala/scalan/Base.scala +++ b/sc/shared/src/main/scala/scalan/Base.scala @@ -168,7 +168,7 @@ abstract class Base { scalan: Scalan => /** Create a copy of this definition applying the given transformer to all `syms`. */ def transform(t: Transformer): Def[T] = - !!!(s"Cannot transfrom definition using transform($this)", self) + !!!(s"Cannot transform definition using transform($this)", self) /** Clone this definition transforming all symbols using `t`. * If new Def[A] is created, it is added to the graph with collapsing and rewriting. diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index 5ddcdfa946..c8238f43e2 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala @@ -2,6 +2,7 @@ package sigmastate.eval import org.ergoplatform._ import scalan.MutableLazy +import sigma.ast.SCollection.SByteArray import sigma.{SigmaException, ast} import sigma.ast.TypeCodes.LastConstantCode import sigma.ast.Value.Typed @@ -536,6 +537,11 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => val e = stypeToElem(optTpe.elemType) ctx.getVar(id)(e) + case DeserializeContext(id, tpe) => + val e = stypeToElem(tpe) + val og = OptionGet(mkGetVar(id, SByteArray)) + sigmaDslBuilder.deserialize(asRep[Coll[Byte]](eval(og)))(e) + case ValUse(valId, _) => env.getOrElse(valId, !!!(s"ValUse $valId not found in environment $env")) diff --git a/sc/shared/src/main/scala/special/sigma/SigmaDslUnit.scala b/sc/shared/src/main/scala/special/sigma/SigmaDslUnit.scala index 48548226a5..26addccf8d 100644 --- a/sc/shared/src/main/scala/special/sigma/SigmaDslUnit.scala +++ b/sc/shared/src/main/scala/special/sigma/SigmaDslUnit.scala @@ -112,6 +112,7 @@ package sigma { /** This method will be used in v6.0 to handle CreateAvlTree operation in GraphBuilding */ def avlTree(operationFlags: Ref[Byte], digest: Ref[Coll[Byte]], keyLength: Ref[Int], valueLengthOpt: Ref[WOption[Int]]): Ref[AvlTree]; def xor(l: Ref[Coll[Byte]], r: Ref[Coll[Byte]]): Ref[Coll[Byte]] + def deserialize[T](bytes: Ref[Coll[Byte]])(implicit cT: Elem[T]): Ref[T] }; trait CostModelCompanion; trait BigIntCompanion; diff --git a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala index 70fb35c329..1231f47693 100644 --- a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -1941,6 +1941,13 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { Array[AnyRef](l, r), true, false, element[Coll[Byte]])) } + + override def deserialize[T](l: Ref[Coll[Byte]])(implicit cT: Elem[T]): Ref[T] = { + asRep[T](mkMethodCall(self, + SigmaDslBuilderClass.getMethod("deserialize", classOf[Sym], classOf[Elem[_]]), + Array[AnyRef](l, cT), + true, false, element[T])) + } } implicit object LiftableSigmaDslBuilder @@ -2100,6 +2107,13 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { Array[AnyRef](l, r), true, true, element[Coll[Byte]])) } + + def deserialize[T](bytes: Ref[Coll[Byte]])(implicit cT: Elem[T]): Ref[T] = { + asRep[T](mkMethodCall(source, + SigmaDslBuilderClass.getMethod("deserialize", classOf[Sym], classOf[Elem[_]]), + Array[AnyRef](bytes, cT), + true, true, element[T])) + } } // entityUnref: single unref method for each type family diff --git a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala index 46222d9fb1..b398b6808c 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala @@ -322,7 +322,7 @@ class SigmaDslTesting extends AnyPropSpec // Compile script the same way it is performed by applications (i.e. via Ergo Appkit) val prop = compile(env, code)(IR).asSigmaProp - // Add additional oparations which are not yet implemented in ErgoScript compiler + // Add additional operations which are not yet implemented in ErgoScript compiler val multisig = AtLeast( IntConstant(2), Array( diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 9f8d3c2f79..e8d355ac24 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -60,7 +60,8 @@ class BasicOpsSpecification extends CompilerTestingCommons "proofVar2" -> CAnyValue(propVar2) ) - def test(name: String, env: ScriptEnv, + def test(name: String, + env: ScriptEnv, ext: Seq[VarBinding], script: String, propExp: SValue, diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/ExecuteFromExamplesSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/ExecuteFromExamplesSpecification.scala index b75b404aed..741b4829cf 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/ExecuteFromExamplesSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/ExecuteFromExamplesSpecification.scala @@ -9,8 +9,6 @@ import sigma.ast.ByteArrayConstant class ExecuteFromExamplesSpecification extends CompilerTestingCommons { suite => implicit lazy val IR = new TestingIRContext - private val reg1 = ErgoBox.nonMandatoryRegisters(0) - case class OracleContract[Spec <: ContractSpec] (alice: Spec#ProvingParty) (implicit val spec: Spec) extends SigmaContractSyntax with StdContracts @@ -40,8 +38,7 @@ class ExecuteFromExamplesSpecification extends CompilerTestingCommons { suite => lazy val alice = spec.ProvingParty("Alice") - // TODO soft-fork: related to https://github.com/ScorexFoundation/sigmastate-interpreter/issues/443 - ignore("Execute from var example (ErgoDsl)") { + property("Execute from var example (ErgoDsl)") { val contract = OracleContract[spec.type](alice)(spec) import contract.spec._ From 690a3e2ec756564f78e0b120d943a5b58fd78df7 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 7 May 2024 19:10:08 +0300 Subject: [PATCH 10/25] Global.deserialize method --- .../sigma/reflection/ReflectionData.scala | 3 ++ .../src/main/scala/sigma/ast/methods.scala | 34 ++++++++++++++++--- .../scala/sigmastate/eval/GraphBuilding.scala | 6 +++- .../special/sigma/impl/SigmaDslImpl.scala | 4 ++- .../utxo/BasicOpsSpecification.scala | 23 +++++++++++++ 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala b/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala index 028e68bf72..cecc0f91bd 100644 --- a/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala +++ b/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala @@ -443,6 +443,9 @@ object ReflectionData { }, mkMethod(clazz, "decodePoint", Array[Class[_]](cColl)) { (obj, args) => obj.asInstanceOf[SigmaDslBuilder].decodePoint(args(0).asInstanceOf[Coll[Byte]]) + }, + mkMethod(clazz, "deserialize", Array[Class[_]](cColl, classOf[RType[_]])) { (obj, args) => + obj.asInstanceOf[SigmaDslBuilder].deserialize(args(0).asInstanceOf[Coll[Byte]])(args(1).asInstanceOf[RType[_]]) } ) ) diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index e4cf0007e0..9df1d4b456 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -4,8 +4,9 @@ import org.ergoplatform._ import org.ergoplatform.validation._ import sigma._ import sigma.ast.SCollection.{SBooleanArray, SBoxArray, SByteArray, SByteArray2, SHeaderArray} +import sigma.ast.SContextMethods.ContextFuncDom import sigma.ast.SMethod.{MethodCallIrBuilder, MethodCostFunc, javaMethodOf} -import sigma.ast.SType.TypeCode +import sigma.ast.SType.{TypeCode, paramT, tT} import sigma.ast.syntax.{SValue, ValueOps} import sigma.data.OverloadHack.Overloaded1 import sigma.data.{DataValueComparer, KeyValueColl, Nullable, RType, SigmaConstants} @@ -1510,6 +1511,11 @@ case object SGlobalMethods extends MonoTypeMethods { .withInfo(Xor, "Byte-wise XOR of two collections of bytes", ArgInfo("left", "left operand"), ArgInfo("right", "right operand")) + lazy val deserializeMethod = SMethod( + this, "deserialize", SFunc(Array(SGlobal, SByteArray), tT, Array(paramT)), 3, Xor.costKind) // todo: cost + .withInfo(Xor, "Byte-wise XOR of two collections of bytes", + ArgInfo("left", "left operand"), ArgInfo("right", "right operand")) + /** Implements evaluation of Global.xor method call ErgoTree node. * Called via reflection based on naming convention. * @see SMethod.evalMethod, Xor.eval, Xor.xorWithCosting @@ -1519,9 +1525,27 @@ case object SGlobalMethods extends MonoTypeMethods { Xor.xorWithCosting(ls, rs) } - protected override def getMethods() = super.getMethods() ++ Seq( - groupGeneratorMethod, - xorMethod - ) + + def deserialize_eval[T](mc: MethodCall, G: SigmaDslBuilder, bytes: Coll[Byte], cT: RType[T]) + (implicit E: ErgoTreeEvaluator): T = { + E.addSeqCost(Xor.costKind, bytes.length, Xor.opDesc) { () => // todo: cost + G.deserialize(bytes)(cT) + } + } + + protected override def getMethods() = super.getMethods() ++ { + if (VersionContext.current.isV6SoftForkActivated) { + Seq( + groupGeneratorMethod, + xorMethod, + deserializeMethod + ) + } else { + Seq( + groupGeneratorMethod, + xorMethod + ) + } + } } diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index c8238f43e2..9369eac09e 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala @@ -3,7 +3,7 @@ package sigmastate.eval import org.ergoplatform._ import scalan.MutableLazy import sigma.ast.SCollection.SByteArray -import sigma.{SigmaException, ast} +import sigma.{SigmaException, VersionContext, ast} import sigma.ast.TypeCodes.LastConstantCode import sigma.ast.Value.Typed import sigma.ast._ @@ -1139,6 +1139,10 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => val c1 = asRep[Coll[Byte]](argsV(0)) val c2 = asRep[Coll[Byte]](argsV(1)) g.xor(c1, c2) + case SGlobalMethods.deserializeMethod.name if VersionContext.current.isV6SoftForkActivated => + val c1 = asRep[Coll[Byte]](argsV(0)) + val c2 = argsV(1).asInstanceOf[Elem[_]] + g.deserialize(c1)(c2) case _ => throwError } case _ => throwError diff --git a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala index 1231f47693..df1270315c 100644 --- a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -2131,7 +2131,9 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { override protected def collectMethods: Map[RMethod, MethodDesc] = { super.collectMethods ++ Elem.declaredMethods(RClass(classOf[SigmaDslBuilder]), RClass(classOf[SSigmaDslBuilder]), Set( - "Colls", "verifyZK", "atLeast", "allOf", "allZK", "anyOf", "anyZK", "xorOf", "sigmaProp", "blake2b256", "sha256", "byteArrayToBigInt", "longToByteArray", "byteArrayToLong", "proveDlog", "proveDHTuple", "groupGenerator", "substConstants", "decodePoint", "avlTree", "xor" + "Colls", "verifyZK", "atLeast", "allOf", "allZK", "anyOf", "anyZK", "xorOf", "sigmaProp", "blake2b256", "sha256", + "byteArrayToBigInt", "longToByteArray", "byteArrayToLong", "proveDlog", "proveDHTuple", "groupGenerator", "substConstants", + "decodePoint", "avlTree", "xor", "deserialize" )) } } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index e8d355ac24..eec55ae4cc 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -2,7 +2,9 @@ package sigmastate.utxo import org.ergoplatform.ErgoBox.{AdditionalRegisters, R6, R8} import org.ergoplatform._ +import scorex.util.encode.Base16 import sigma.Extensions.ArrayOps +import sigma.VersionContext.V6SoftForkVersion import sigma.ast.SCollection.SByteArray import sigma.ast.SType.AnyOps import sigma.data.{AvlTreeData, CAnyValue, CSigmaDslBuilder} @@ -159,6 +161,27 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } + property("deserialize - int") { + + val bytes = Base16.encode(ValueSerializer.serialize(IntConstant(5.toShort))) + + if (activatedVersionInTests < V6SoftForkVersion) { + /* an [sigmastate.exceptions.MethodNotFound] should be thrownBy { + test("executeFromVar", env, ext, + s"Global.deserialize[Int](fromBase16(\"$bytes\")) == 5", + null, + true + ) + } */ + } else { + test("executeFromVar", env, ext, + s"Global.deserialize[Int](fromBase16(\"$bytes\")) == 5", + null, + true + ) + } + } + property("executeFromVar") { val script = GT(Height, IntConstant(1)).toSigmaProp val scriptBytes = ValueSerializer.serialize(script) From 023ad097483a619df4da836d4a4f52bbad29e933 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 8 May 2024 23:15:22 +0300 Subject: [PATCH 11/25] deserialize int - test passing --- .../src/main/scala/sigma/ast/methods.scala | 10 ++- .../serialization/MethodCallSerializer.scala | 16 ++++- .../scala/sigmastate/eval/GraphBuilding.scala | 30 +++++++-- .../scala/sigmastate/eval/TreeBuilding.scala | 14 +++- .../scala/sigmastate/lang/SigmaTyper.scala | 17 ++++- .../special/sigma/impl/SigmaDslImpl.scala | 14 +++- .../scala/sigmastate/CompilerTestsBase.scala | 2 +- .../utxo/BasicOpsSpecification.scala | 65 ++++++++++++++----- 8 files changed, 136 insertions(+), 32 deletions(-) diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index 9df1d4b456..e948346868 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -2,9 +2,9 @@ package sigma.ast import org.ergoplatform._ import org.ergoplatform.validation._ +import sigma.Evaluation.stypeToRType import sigma._ import sigma.ast.SCollection.{SBooleanArray, SBoxArray, SByteArray, SByteArray2, SHeaderArray} -import sigma.ast.SContextMethods.ContextFuncDom import sigma.ast.SMethod.{MethodCallIrBuilder, MethodCostFunc, javaMethodOf} import sigma.ast.SType.{TypeCode, paramT, tT} import sigma.ast.syntax.{SValue, ValueOps} @@ -1511,8 +1511,11 @@ case object SGlobalMethods extends MonoTypeMethods { .withInfo(Xor, "Byte-wise XOR of two collections of bytes", ArgInfo("left", "left operand"), ArgInfo("right", "right operand")) + lazy val desJava = ownerType.reprClass.getMethod("deserialize", classOf[Coll[Byte]], classOf[RType[_]]) + lazy val deserializeMethod = SMethod( this, "deserialize", SFunc(Array(SGlobal, SByteArray), tT, Array(paramT)), 3, Xor.costKind) // todo: cost + .copy(irInfo = MethodIRInfo(None, Some(desJava), None)) .withInfo(Xor, "Byte-wise XOR of two collections of bytes", ArgInfo("left", "left operand"), ArgInfo("right", "right operand")) @@ -1526,8 +1529,9 @@ case object SGlobalMethods extends MonoTypeMethods { } - def deserialize_eval[T](mc: MethodCall, G: SigmaDslBuilder, bytes: Coll[Byte], cT: RType[T]) - (implicit E: ErgoTreeEvaluator): T = { + def deserialize_eval(mc: MethodCall, G: SigmaDslBuilder, bytes: Coll[Byte]) + (implicit E: ErgoTreeEvaluator): Any = { + val cT = stypeToRType(mc.tpe) E.addSeqCost(Xor.costKind, bytes.length, Xor.opDesc) { () => // todo: cost G.deserialize(bytes)(cT) } diff --git a/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala b/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala index 319a4284e2..693e66d57e 100644 --- a/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala @@ -1,11 +1,12 @@ package sigma.serialization import sigma.ast.syntax._ -import sigma.ast.{MethodCall, SContextMethods, SMethod, SType, STypeSubst, Value, ValueCompanion} +import sigma.ast.{MethodCall, SContextMethods, SGlobalMethods, SMethod, SType, STypeSubst, Value, ValueCompanion} import sigma.util.safeNewArray import SigmaByteWriter._ import debox.cfor import sigma.ast.SContextMethods.BlockchainContextMethodNames +import sigma.ast.SType.tT import sigma.serialization.CoreByteWriter.{ArgInfo, DataInfo} case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[SType]], STypeSubst) => Value[SType]) @@ -15,6 +16,7 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S val methodCodeInfo: DataInfo[Byte] = ArgInfo("methodCode", "a code of the method") val objInfo: DataInfo[SValue] = ArgInfo("obj", "receiver object of this method call") val argsInfo: DataInfo[Seq[SValue]] = ArgInfo("args", "arguments of the method call") + val typeInfo: DataInfo[SType] = ArgInfo("type", "expected type of method result") val argsItemInfo = valuesItemInfo(argsInfo) override def serialize(mc: MethodCall, w: SigmaByteWriter): Unit = { @@ -23,6 +25,9 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S w.putValue(mc.obj, objInfo) assert(mc.args.nonEmpty) w.putValues(mc.args, argsInfo, argsItemInfo) + if(mc.method.name == SGlobalMethods.deserializeMethod.name){ + w.putType(mc.tpe, typeInfo) + } } /** The SMethod instances in STypeCompanions may have type STypeIdent in methods types, @@ -57,10 +62,17 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S val specMethod = method.specializeFor(obj.tpe, types) + val subst: STypeSubst = if(method.name == SGlobalMethods.deserializeMethod.name) { + val tpe = r.getType() + Map(tT -> tpe) + } else { + Map.empty + } + var isUsingBlockchainContext = specMethod.objType == SContextMethods && BlockchainContextMethodNames.contains(method.name) r.wasUsingBlockchainContext ||= isUsingBlockchainContext - cons(obj, specMethod, args, Map.empty) + cons(obj, specMethod, args, subst) } } diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index 9369eac09e..31cb06e698 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala @@ -20,6 +20,25 @@ import sigma.serialization.OpCodes import scala.collection.mutable.ArrayBuffer + +case class DeserializeBytes[V <: SType](bytes: Value[SByteArray], tpe: V) extends NotReadyValue[V] { + /** The companion node descriptor with opCode, cost and other metadata. */ + override def companion: ValueCompanion = ??? + + /** Every value represents an operation and that operation can be associated with a function type, + * describing functional meaning of the operation, kind of operation signature. + * Thus, we can obtain global operation identifiers by combining Value.opName with Value.opType, + * so that if (v1.opName == v2.opName) && (v1.opType == v2.opType) then v1 and v2 are functionally + * point-wise equivalent. + * This in particular means that if two _different_ ops have the same opType they _should_ have + * different opNames. + * Thus defined op ids are used in a v4.x Cost Model - a table of all existing primitives coupled with + * performance parameters. + * */ + override def opType: SFunc = Value.notSupportedError(this, "opType") +} + + /** Perform translation of typed expression given by [[Value]] to a graph in IRContext. * Which be than be translated to [[ErgoTree]] by using [[TreeBuilding]]. * @@ -537,10 +556,11 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => val e = stypeToElem(optTpe.elemType) ctx.getVar(id)(e) + case DeserializeBytes(bytes, tpe) => + sigmaDslBuilder.deserialize(asRep[Coll[Byte]](eval(bytes)))(stypeToElem(tpe)) + case DeserializeContext(id, tpe) => - val e = stypeToElem(tpe) - val og = OptionGet(mkGetVar(id, SByteArray)) - sigmaDslBuilder.deserialize(asRep[Coll[Byte]](eval(og)))(e) + eval(DeserializeBytes(OptionGet(mkGetVar(id, SByteArray)), tpe)) case ValUse(valId, _) => env.getOrElse(valId, !!!(s"ValUse $valId not found in environment $env")) @@ -921,7 +941,7 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => sigmaDslBuilder.decodePoint(bytes) // fallback rule for MethodCall, should be the last case in the list - case sigma.ast.MethodCall(obj, method, args, _) => + case sigma.ast.MethodCall(obj, method, args, typeSubst) => val objV = eval(obj) val argsV = args.map(eval) (objV, method.objType) match { @@ -1141,7 +1161,7 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => g.xor(c1, c2) case SGlobalMethods.deserializeMethod.name if VersionContext.current.isV6SoftForkActivated => val c1 = asRep[Coll[Byte]](argsV(0)) - val c2 = argsV(1).asInstanceOf[Elem[_]] + val c2 = stypeToElem(method.stype.tRange.withSubstTypes(typeSubst)) g.deserialize(c1)(c2) case _ => throwError } diff --git a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala index 27f659c1ed..09dc06535f 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -3,6 +3,7 @@ package sigmastate.eval import sigma.ast._ import org.ergoplatform._ +import sigma.ast.SType.tT import sigma.ast.syntax.ValueOps import sigma.serialization.OpCodes._ import sigma.serialization.ConstantStore @@ -218,6 +219,10 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => val tpe = elemToSType(eVar) mkGetVar(id, tpe) + case SDBM.deserialize(g, bytes, eVar) => + val tpe = elemToSType(eVar) + builder.mkMethodCall(recurse(g), SGlobalMethods.deserializeMethod, IndexedSeq(recurse(bytes)), Map(tT -> tpe): STypeSubst) + case BIM.subtract(In(x), In(y)) => mkArith(x.asNumValue, y.asNumValue, MinusCode) case BIM.add(In(x), In(y)) => @@ -397,13 +402,18 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => mkMultiplyGroup(obj.asGroupElement, arg.asGroupElement) // Fallback MethodCall rule: should be the last in this list of cases - case Def(MethodCall(objSym, m, argSyms, _)) => + case d@Def(MethodCall(objSym, m, argSyms, _)) => val obj = recurse[SType](objSym) val args = argSyms.collect { case argSym: Sym => recurse[SType](argSym) } MethodsContainer.getMethod(obj.tpe, m.getName) match { case Some(method) => val specMethod = method.specializeFor(obj.tpe, args.map(_.tpe)) - builder.mkMethodCall(obj, specMethod, args.toIndexedSeq, Map()) + val typeSubst: STypeSubst = if(m.getName == SGlobalMethods.deserializeMethod.name) { + Map.empty + } else { + Map.empty + } + builder.mkMethodCall(obj, specMethod, args.toIndexedSeq, typeSubst) case None => error(s"Cannot find method ${m.getName} in object $obj") } diff --git a/sc/shared/src/main/scala/sigmastate/lang/SigmaTyper.scala b/sc/shared/src/main/scala/sigmastate/lang/SigmaTyper.scala index 7fd6dadd45..991b3ce064 100644 --- a/sc/shared/src/main/scala/sigmastate/lang/SigmaTyper.scala +++ b/sc/shared/src/main/scala/sigmastate/lang/SigmaTyper.scala @@ -1,6 +1,5 @@ package sigmastate.lang -import org.ergoplatform._ import sigma.ast.SCollection.{SBooleanArray, SByteArray} import sigma.ast._ import sigma.ast.syntax.SValue @@ -11,6 +10,7 @@ import SigmaPredef._ import sigma.ast.syntax._ import sigma.exceptions.TyperException import sigma.serialization.OpCodes +import sigmastate.eval.DeserializeBytes import scala.collection.mutable.ArrayBuffer @@ -33,7 +33,7 @@ class SigmaTyper(val builder: SigmaBuilder, private def processGlobalMethod(srcCtx: Nullable[SourceContext], method: SMethod, - args: IndexedSeq[SValue]) = { + args: IndexedSeq[SValue]): SValue = { val global = Global.withPropagatedSrcCtx(srcCtx) val node = for { pf <- method.irInfo.irBuilder if lowerMethodCalls @@ -133,6 +133,19 @@ class SigmaTyper(val builder: SigmaBuilder, val newObj = assignType(env, obj) val newArgs = args.map(assignType(env, _)) obj.tpe match { + case SGlobal => + SGlobalMethods.method(n) match { + case Some(method) => + val srcCtx = sel.sourceContext + if(method.name == SGlobalMethods.deserializeMethod.name) { + val global = Global.withPropagatedSrcCtx(srcCtx) + DeserializeBytes(args(0).asInstanceOf[Value[SByteArray]], rangeTpe) + } else { + processGlobalMethod(srcCtx, method, newArgs) + } + case _ => + error(s"Cannot find Global method: $n", bound.sourceContext) + } case p: SProduct => MethodsContainer.getMethod(p, n) match { case Some(method @ SMethod(_, _, genFunTpe @ SFunc(_, _, _), _, _, _, _, _)) => diff --git a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala index df1270315c..efdb3dbda0 100644 --- a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -1944,7 +1944,7 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { override def deserialize[T](l: Ref[Coll[Byte]])(implicit cT: Elem[T]): Ref[T] = { asRep[T](mkMethodCall(self, - SigmaDslBuilderClass.getMethod("deserialize", classOf[Sym], classOf[Elem[_]]), + SigmaDslBuilderClass.getMethod("deserialize", classOf[Sym], classOf[Elem[T]]), Array[AnyRef](l, cT), true, false, element[T])) } @@ -2110,7 +2110,7 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { def deserialize[T](bytes: Ref[Coll[Byte]])(implicit cT: Elem[T]): Ref[T] = { asRep[T](mkMethodCall(source, - SigmaDslBuilderClass.getMethod("deserialize", classOf[Sym], classOf[Elem[_]]), + SigmaDslBuilderClass.getMethod("deserialize", classOf[Sym], classOf[Elem[T]]), Array[AnyRef](bytes, cT), true, true, element[T])) } @@ -2312,6 +2312,16 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = unapply(exp.node) } + object deserialize { + def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Elem[T]) forSome {type T}] = d match { + case MethodCall(receiver, method, args, _) if method.getName == "deserialize" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => + val res = (receiver, args(0), args(1)) + Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Elem[T]) forSome {type T}]] + case _ => Nullable.None + } + def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Elem[T]) forSome {type T}] = unapply(exp.node) + } + /** This is necessary to handle CreateAvlTree in GraphBuilding (v6.0) */ object avlTree { def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Byte], Ref[Coll[Byte]], Ref[Int], Ref[WOption[Int]])] = d match { diff --git a/sc/shared/src/test/scala/sigmastate/CompilerTestsBase.scala b/sc/shared/src/test/scala/sigmastate/CompilerTestsBase.scala index 28f907c199..a5ae8f1bce 100644 --- a/sc/shared/src/test/scala/sigmastate/CompilerTestsBase.scala +++ b/sc/shared/src/test/scala/sigmastate/CompilerTestsBase.scala @@ -38,7 +38,7 @@ trait CompilerTestsBase extends TestsBase { def checkSerializationRoundTrip(v: SValue): Unit = { val compiledTreeBytes = ValueSerializer.serialize(v) withClue(s"(De)Serialization roundtrip failed for the tree:") { - ValueSerializer.deserialize(compiledTreeBytes) shouldEqual v + ValueSerializer.deserialize(compiledTreeBytes) shouldEqual v } } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index eec55ae4cc..ed84c02c33 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -3,6 +3,7 @@ package sigmastate.utxo import org.ergoplatform.ErgoBox.{AdditionalRegisters, R6, R8} import org.ergoplatform._ import scorex.util.encode.Base16 +import sigma.Colls import sigma.Extensions.ArrayOps import sigma.VersionContext.V6SoftForkVersion import sigma.ast.SCollection.SByteArray @@ -87,8 +88,9 @@ class BasicOpsSpecification extends CompilerTestingCommons // is not supported by ErgoScript Compiler) // In such cases we use expected property as the property to test propExp.asSigmaProp - } else + } else { compile(env, script).asBoolValue.toSigmaProp + } if (propExp != null) prop shouldBe propExp @@ -163,34 +165,67 @@ class BasicOpsSpecification extends CompilerTestingCommons property("deserialize - int") { - val bytes = Base16.encode(ValueSerializer.serialize(IntConstant(5.toShort))) + val bytes = Base16.encode(ValueSerializer.serialize(IntConstant(5))) if (activatedVersionInTests < V6SoftForkVersion) { - /* an [sigmastate.exceptions.MethodNotFound] should be thrownBy { - test("executeFromVar", env, ext, + an [sigma.exceptions.TyperException] should be thrownBy { + test("deserialize", env, ext, s"Global.deserialize[Int](fromBase16(\"$bytes\")) == 5", null, true ) - } */ + } } else { - test("executeFromVar", env, ext, - s"Global.deserialize[Int](fromBase16(\"$bytes\")) == 5", + test("deserialize", env, ext, + s"{ val ba = fromBase16(\"$bytes\"); Global.deserialize[Int](ba) == 5 }", null, true ) } } +/* + todo: fix + property("deserialize - coll") { - property("executeFromVar") { - val script = GT(Height, IntConstant(1)).toSigmaProp - val scriptBytes = ValueSerializer.serialize(script) - val customExt = Seq(21.toByte -> ByteArrayConstant(scriptBytes)) - test("executeFromVar", env, customExt, - "executeFromVar[SigmaProp](21)", - null, - true + val bytes = Base16.encode(ValueSerializer.serialize(CollectionConstant[SInt.type](Colls.fromArray(Array(IntConstant(5).value)), SInt))) + + if (activatedVersionInTests < V6SoftForkVersion) { + an [sigma.exceptions.TyperException] should be thrownBy { + test("deserialize", env, ext, + s"Global.deserialize[Coll[Int]](fromBase16(\"$bytes\")).apply(0) == 5", + null, + true + ) + } + } else { + test("deserialize", env, ext, + s"Global.deserialize[Coll[Int]](fromBase16(\"$bytes\")).apply(0) == 5", + null, + true + ) + } + } + + property("getVar") { + test("getVar", env, ext, + "{ allOf(Coll(CONTEXT.getVar[Boolean](trueVar).get, true, true)) }", + AND(GetVarBoolean(booleanVar).get, TrueLeaf, TrueLeaf).toSigmaProp ) + } */ + + property("executeFromVar") { + if (activatedVersionInTests < V6SoftForkVersion) { + + } else { + val script = GT(Height, IntConstant(1)).toSigmaProp + val scriptBytes = ValueSerializer.serialize(script) + val customExt = Seq(21.toByte -> ByteArrayConstant(scriptBytes)) + test("executeFromVar", env, customExt, + "executeFromVar[SigmaProp](21)", + null, + true + ) + } } property("Relation operations") { From 76481823fa7f16a7e81b89f95629e264d9b05a2a Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 9 May 2024 11:21:15 +0300 Subject: [PATCH 12/25] unused code removal --- sc/shared/src/main/scala/scalan/Base.scala | 6 ------ .../src/main/scala/sigmastate/eval/GraphBuilding.scala | 5 +++-- .../src/main/scala/sigmastate/eval/TreeBuilding.scala | 9 ++------- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/sc/shared/src/main/scala/scalan/Base.scala b/sc/shared/src/main/scala/scalan/Base.scala index dd4079054f..aecb9cb2ec 100644 --- a/sc/shared/src/main/scala/scalan/Base.scala +++ b/sc/shared/src/main/scala/scalan/Base.scala @@ -202,12 +202,6 @@ abstract class Base { scalan: Scalan => } } - /** Logical AND between two pattern matches of the save value `x`. - * Can be used to construct patterns like `case P1 && P2 => ...` */ - object && { - def unapply[T](x: T): Option[(T,T)] = Some((x, x)) - } - /** Base class for virtualized instances of type companions. * Each virtualized entity type (trait or class) may have virtualized companion class. */ abstract class CompanionDef[T] extends Def[T] { diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index 31cb06e698..d20b10f7d4 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala @@ -559,8 +559,9 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => case DeserializeBytes(bytes, tpe) => sigmaDslBuilder.deserialize(asRep[Coll[Byte]](eval(bytes)))(stypeToElem(tpe)) - case DeserializeContext(id, tpe) => - eval(DeserializeBytes(OptionGet(mkGetVar(id, SByteArray)), tpe)) + case d@DeserializeContext(_, _) => + ??? + // eval(DeserializeBytes(OptionGet(mkGetVar(id, SByteArray)), tpe)) case ValUse(valId, _) => env.getOrElse(valId, !!!(s"ValUse $valId not found in environment $env")) diff --git a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala index 09dc06535f..52d35736dc 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -402,18 +402,13 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => mkMultiplyGroup(obj.asGroupElement, arg.asGroupElement) // Fallback MethodCall rule: should be the last in this list of cases - case d@Def(MethodCall(objSym, m, argSyms, _)) => + case Def(MethodCall(objSym, m, argSyms, _)) => val obj = recurse[SType](objSym) val args = argSyms.collect { case argSym: Sym => recurse[SType](argSym) } MethodsContainer.getMethod(obj.tpe, m.getName) match { case Some(method) => val specMethod = method.specializeFor(obj.tpe, args.map(_.tpe)) - val typeSubst: STypeSubst = if(m.getName == SGlobalMethods.deserializeMethod.name) { - Map.empty - } else { - Map.empty - } - builder.mkMethodCall(obj, specMethod, args.toIndexedSeq, typeSubst) + builder.mkMethodCall(obj, specMethod, args.toIndexedSeq, Map.empty) case None => error(s"Cannot find method ${m.getName} in object $obj") } From 79b4d11a370788bbb9acb869c45b8169f01947ff Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 9 May 2024 13:32:04 +0300 Subject: [PATCH 13/25] executeFromVar is passing for SigmaProp --- sc/shared/src/main/scala/scalan/Base.scala | 9 +++- .../scala/sigmastate/eval/GraphBuilding.scala | 3 +- .../scala/sigmastate/eval/TreeBuilding.scala | 3 ++ .../utxo/BasicOpsSpecification.scala | 53 ++++++++++--------- 4 files changed, 40 insertions(+), 28 deletions(-) diff --git a/sc/shared/src/main/scala/scalan/Base.scala b/sc/shared/src/main/scala/scalan/Base.scala index aecb9cb2ec..c18eddfc14 100644 --- a/sc/shared/src/main/scala/scalan/Base.scala +++ b/sc/shared/src/main/scala/scalan/Base.scala @@ -1,6 +1,7 @@ package scalan import debox.{cfor, Buffer => DBuffer} +import sigma.ast.{DeserializeContext, SType} import sigma.data.{AVHashMap, Nullable, RType} import sigma.data.OverloadHack.Overloaded1 import sigma.util.StringUtil @@ -202,6 +203,13 @@ abstract class Base { scalan: Scalan => } } + case class DeserializeContextDef[V <: SType](d: DeserializeContext[V]) extends Def[V] { + /** Type of a resulting value produced by the operation represented by this definition. + * For example, if this definition represents application of `+: (Int, Int) => Int` operation + * then the result type is Int and `resultType` should return IntElement. */ + override def resultType: Elem[V] = ??? + } + /** Base class for virtualized instances of type companions. * Each virtualized entity type (trait or class) may have virtualized companion class. */ abstract class CompanionDef[T] extends Def[T] { @@ -376,7 +384,6 @@ abstract class Base { scalan: Scalan => /** Returns the string like `x45: Int = Const(10)` */ def toStringWithDefinition: String def varNameWithType = varName + ":" + elem.name - } /** Untyped shortcut sinonim of Ref, which is used as untyped reference to graph nodes (definitions). diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index d20b10f7d4..3be5ef6db1 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala @@ -560,8 +560,7 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => sigmaDslBuilder.deserialize(asRep[Coll[Byte]](eval(bytes)))(stypeToElem(tpe)) case d@DeserializeContext(_, _) => - ??? - // eval(DeserializeBytes(OptionGet(mkGetVar(id, SByteArray)), tpe)) + DeserializeContextDef(d) case ValUse(valId, _) => env.getOrElse(valId, !!!(s"ValUse $valId not found in environment $env")) diff --git a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala index 52d35736dc..3fe2f2f4ce 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -188,6 +188,9 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => val tpe = elemToSType(s.elem) mkConstant[tpe.type](wc.constValue.asInstanceOf[tpe.WrappedType], tpe) + case Def(DeserializeContextDef(d)) => + d + case Def(IsContextProperty(v)) => v case s if s == sigmaDslBuilder => Global diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index ed84c02c33..5172109674 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -166,21 +166,16 @@ class BasicOpsSpecification extends CompilerTestingCommons property("deserialize - int") { val bytes = Base16.encode(ValueSerializer.serialize(IntConstant(5))) + def deserTest() = {test("deserialize", env, ext, + s"{ val ba = fromBase16(\"$bytes\"); Global.deserialize[Int](ba) == 5 }", + null, + true + )} if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy { - test("deserialize", env, ext, - s"Global.deserialize[Int](fromBase16(\"$bytes\")) == 5", - null, - true - ) - } + an [sigma.exceptions.TyperException] should be thrownBy deserTest() } else { - test("deserialize", env, ext, - s"{ val ba = fromBase16(\"$bytes\"); Global.deserialize[Int](ba) == 5 }", - null, - true - ) + deserTest() } } /* @@ -213,21 +208,29 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } */ - property("executeFromVar") { - if (activatedVersionInTests < V6SoftForkVersion) { - - } else { - val script = GT(Height, IntConstant(1)).toSigmaProp - val scriptBytes = ValueSerializer.serialize(script) - val customExt = Seq(21.toByte -> ByteArrayConstant(scriptBytes)) - test("executeFromVar", env, customExt, - "executeFromVar[SigmaProp](21)", - null, - true - ) - } + property("executeFromVar - SigmaProp") { + val script = GT(Height, IntConstant(-1)).toSigmaProp + val scriptBytes = ValueSerializer.serialize(script) + val customExt = Seq(21.toByte -> ByteArrayConstant(scriptBytes)) + test("executeFromVar", env, customExt, + "executeFromVar[SigmaProp](21)", + null, + true + ) } + /* todo: fix + property("executeFromVar - Coll[Byte]") { + val bytes = ByteArrayConstant(Colls.fromArray(Array.fill(5)(1.toByte))) + val valueBytes = ValueSerializer.serialize(bytes) + val customExt = Seq(21.toByte -> ByteArrayConstant(valueBytes)) + test("executeFromVar", env, customExt, + "{val ba = executeFromVar[Coll[Byte]](21); ba.size == 5 }", + null, + true + ) + } */ + property("Relation operations") { test("R1", env, ext, "{ allOf(Coll(getVar[Boolean](trueVar).get, true, true)) }", From a470406738644485606ee2898d1afb7a8d36d341 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 9 May 2024 14:28:39 +0300 Subject: [PATCH 14/25] more executeFromVar and deserialize tests, all passing --- sc/shared/src/main/scala/scalan/Base.scala | 4 +-- .../scala/sigmastate/eval/GraphBuilding.scala | 5 ++-- .../scala/sigmastate/eval/TreeBuilding.scala | 2 +- .../utxo/BasicOpsSpecification.scala | 27 ++++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/sc/shared/src/main/scala/scalan/Base.scala b/sc/shared/src/main/scala/scalan/Base.scala index c18eddfc14..d40a0dabe9 100644 --- a/sc/shared/src/main/scala/scalan/Base.scala +++ b/sc/shared/src/main/scala/scalan/Base.scala @@ -203,11 +203,11 @@ abstract class Base { scalan: Scalan => } } - case class DeserializeContextDef[V <: SType](d: DeserializeContext[V]) extends Def[V] { + case class DeserializeContextDef[V <: SType](d: DeserializeContext[V], e: Elem[V]) extends Def[V] { /** Type of a resulting value produced by the operation represented by this definition. * For example, if this definition represents application of `+: (Int, Int) => Int` operation * then the result type is Int and `resultType` should return IntElement. */ - override def resultType: Elem[V] = ??? + override def resultType: Elem[V] = e } /** Base class for virtualized instances of type companions. diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index 3be5ef6db1..ef78790db7 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala @@ -559,8 +559,9 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => case DeserializeBytes(bytes, tpe) => sigmaDslBuilder.deserialize(asRep[Coll[Byte]](eval(bytes)))(stypeToElem(tpe)) - case d@DeserializeContext(_, _) => - DeserializeContextDef(d) + case d: DeserializeContext[T] => + val e = stypeToElem(d.tpe).asInstanceOf[Elem[T]] + DeserializeContextDef(d, e) case ValUse(valId, _) => env.getOrElse(valId, !!!(s"ValUse $valId not found in environment $env")) diff --git a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala index 3fe2f2f4ce..2071e7b0d1 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -188,7 +188,7 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => val tpe = elemToSType(s.elem) mkConstant[tpe.type](wc.constValue.asInstanceOf[tpe.WrappedType], tpe) - case Def(DeserializeContextDef(d)) => + case Def(DeserializeContextDef(d, _)) => d case Def(IsContextProperty(v)) => v diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 5172109674..5b63afaa44 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -8,7 +8,7 @@ import sigma.Extensions.ArrayOps import sigma.VersionContext.V6SoftForkVersion import sigma.ast.SCollection.SByteArray import sigma.ast.SType.AnyOps -import sigma.data.{AvlTreeData, CAnyValue, CSigmaDslBuilder} +import sigma.data.{AvlTreeData, CAnyValue, CSigmaDslBuilder, ProveDlog} import sigma.util.StringUtil._ import sigma.ast._ import sigma.ast.syntax._ @@ -178,8 +178,7 @@ class BasicOpsSpecification extends CompilerTestingCommons deserTest() } } -/* - todo: fix + property("deserialize - coll") { val bytes = Base16.encode(ValueSerializer.serialize(CollectionConstant[SInt.type](Colls.fromArray(Array(IntConstant(5).value)), SInt))) @@ -187,20 +186,21 @@ class BasicOpsSpecification extends CompilerTestingCommons if (activatedVersionInTests < V6SoftForkVersion) { an [sigma.exceptions.TyperException] should be thrownBy { test("deserialize", env, ext, - s"Global.deserialize[Coll[Int]](fromBase16(\"$bytes\")).apply(0) == 5", + s"{val ba = fromBase16(\"$bytes\"); val coll = Global.deserialize[Coll[Int]](ba); coll(0) == 5 }", null, true ) } } else { test("deserialize", env, ext, - s"Global.deserialize[Coll[Int]](fromBase16(\"$bytes\")).apply(0) == 5", + s"{val ba = fromBase16(\"$bytes\"); val coll = Global.deserialize[Coll[Int]](ba); coll(0) == 5 }", null, true ) } } + /* property("getVar") { test("getVar", env, ext, "{ allOf(Coll(CONTEXT.getVar[Boolean](trueVar).get, true, true)) }", @@ -219,17 +219,26 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - /* todo: fix + property("executeFromVar - Int") { + val valueBytes = ValueSerializer.serialize(Plus(IntConstant(2), IntConstant(3))) + val customExt = Seq(21.toByte -> ByteArrayConstant(valueBytes)) + test("executeFromVar", env, customExt, + "{ executeFromVar[Int](21) == 5 }", + null, + true + ) + } + property("executeFromVar - Coll[Byte]") { - val bytes = ByteArrayConstant(Colls.fromArray(Array.fill(5)(1.toByte))) + val bytes = Slice(ByteArrayConstant(Colls.fromArray(Array.fill(5)(1.toByte))), IntConstant(1), IntConstant(3)) val valueBytes = ValueSerializer.serialize(bytes) val customExt = Seq(21.toByte -> ByteArrayConstant(valueBytes)) test("executeFromVar", env, customExt, - "{val ba = executeFromVar[Coll[Byte]](21); ba.size == 5 }", + "{val ba = executeFromVar[Coll[Byte]](21); ba.size == 2 }", null, true ) - } */ + } property("Relation operations") { test("R1", env, ext, From c1947d46f95e4a8057edb556b1142163caab2ec2 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 9 May 2024 15:05:24 +0300 Subject: [PATCH 15/25] negative test for DeserializeContext in executeFromVar, new stubs for deserialize test --- .../scala/sigma/data/CSigmaDslBuilder.scala | 13 +++-- .../utxo/BasicOpsSpecification.scala | 54 ++++++++++++++----- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index cc5eb3e7d6..7ec227a06c 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -16,6 +16,7 @@ import sigma.validation.SigmaValidationSettings import sigma.{AvlTree, BigInt, Box, Coll, CollBuilder, GroupElement, SigmaDslBuilder, SigmaProp, VersionContext} import java.math.BigInteger +import scala.reflect.ClassTag /** A default implementation of [[SigmaDslBuilder]] interface. * @@ -204,12 +205,16 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => } def deserialize[T](bytes: Coll[Byte])(implicit cT: RType[T]): T = { - val v = ValueSerializer.deserialize(bytes.toArray) - if(stypeToRType(v.tpe) == cT) { - v.asInstanceOf[EvaluatedValue[_]].value.asInstanceOf[T] - } else { + if(!cT.isInstanceOf[PrimitiveType[_]]) { throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: $cT") } + + cT.classTag match { + case ClassTag.Int => scorex.utils.Ints.fromByteArray(bytes.toArray).asInstanceOf[T] + case BoxClassTag => scorex.utils.Ints.fromByteArray(bytes.toArray).asInstanceOf[T] + case _ => + throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: $cT") + } } } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 5b63afaa44..275c32171c 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -3,7 +3,8 @@ package sigmastate.utxo import org.ergoplatform.ErgoBox.{AdditionalRegisters, R6, R8} import org.ergoplatform._ import scorex.util.encode.Base16 -import sigma.Colls +import scorex.utils.Ints +import sigma.{Colls, SigmaProp} import sigma.Extensions.ArrayOps import sigma.VersionContext.V6SoftForkVersion import sigma.ast.SCollection.SByteArray @@ -164,8 +165,7 @@ class BasicOpsSpecification extends CompilerTestingCommons } property("deserialize - int") { - - val bytes = Base16.encode(ValueSerializer.serialize(IntConstant(5))) + val bytes = Base16.encode(Ints.toByteArray(5)) def deserTest() = {test("deserialize", env, ext, s"{ val ba = fromBase16(\"$bytes\"); Global.deserialize[Int](ba) == 5 }", null, @@ -183,23 +183,42 @@ class BasicOpsSpecification extends CompilerTestingCommons val bytes = Base16.encode(ValueSerializer.serialize(CollectionConstant[SInt.type](Colls.fromArray(Array(IntConstant(5).value)), SInt))) - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy { - test("deserialize", env, ext, - s"{val ba = fromBase16(\"$bytes\"); val coll = Global.deserialize[Coll[Int]](ba); coll(0) == 5 }", - null, - true - ) - } - } else { + def deserTest() = { test("deserialize", env, ext, s"{val ba = fromBase16(\"$bytes\"); val coll = Global.deserialize[Coll[Int]](ba); coll(0) == 5 }", null, true ) } + + if (activatedVersionInTests < V6SoftForkVersion) { + an [sigma.exceptions.TyperException] should be thrownBy deserTest() + } else { + an [java.lang.reflect.InvocationTargetException] should be thrownBy deserTest() + } + } + + property("deserialize - long roundtrip") { + + } + + property("deserialize - box") { + + } + + property("deserialize - bigint") { + + } + + property("deserialize - header") { + } + property("deserialize - short") { + + } + + /* property("getVar") { test("getVar", env, ext, @@ -240,6 +259,17 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } + property("executeFromVar - deserialize") { + val script = DeserializeContext(21.toByte, SSigmaProp) + val scriptBytes = ValueSerializer.serialize(script) + val customExt = Seq(21.toByte -> ByteArrayConstant(scriptBytes)) + an [Exception] should be thrownBy test("executeFromVar", env, customExt, + "executeFromVar[SigmaProp](21)", + null, + true + ) + } + property("Relation operations") { test("R1", env, ext, "{ allOf(Coll(getVar[Boolean](trueVar).get, true, true)) }", From cec0adda39dfc9909d795b643c82de35644a07c2 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 9 May 2024 15:35:50 +0300 Subject: [PATCH 16/25] long roundtrip --- .../scala/sigma/data/CSigmaDslBuilder.scala | 7 ++++--- .../sigmastate/utxo/BasicOpsSpecification.scala | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index 7ec227a06c..99f247bc21 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -209,12 +209,13 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: $cT") } - cT.classTag match { - case ClassTag.Int => scorex.utils.Ints.fromByteArray(bytes.toArray).asInstanceOf[T] - case BoxClassTag => scorex.utils.Ints.fromByteArray(bytes.toArray).asInstanceOf[T] + val res = cT.classTag match { + case ClassTag.Int => scorex.utils.Ints.fromByteArray(bytes.toArray) + case ClassTag.Long => scorex.utils.Longs.fromByteArray(bytes.toArray) case _ => throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: $cT") } + res.asInstanceOf[T] } } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 275c32171c..a6630ee48c 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -194,12 +194,27 @@ class BasicOpsSpecification extends CompilerTestingCommons if (activatedVersionInTests < V6SoftForkVersion) { an [sigma.exceptions.TyperException] should be thrownBy deserTest() } else { + // only primitive types are supported, so the test fails an [java.lang.reflect.InvocationTargetException] should be thrownBy deserTest() } } property("deserialize - long roundtrip") { - + def deserTest() = test("deserialize", env, ext, + s"""{ + val l = 5L; + val ba = longToByteArray(l); + Global.deserialize[Long](ba) == l + }""", + null, + true + ) + + if (activatedVersionInTests < V6SoftForkVersion) { + an [sigma.exceptions.TyperException] should be thrownBy deserTest() + } else { + deserTest() + } } property("deserialize - box") { From 838a6172ecd279bb7dad64807ed4a1d470ee416a Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 10 May 2024 18:14:00 +0300 Subject: [PATCH 17/25] box rouundtrip test --- .../main/scala/sigma/data/CSigmaDslBuilder.scala | 15 +++++++-------- .../sigmastate/utxo/BasicOpsSpecification.scala | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index 99f247bc21..035fde1949 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -6,7 +6,7 @@ import org.ergoplatform.validation.ValidationRules import scorex.crypto.hash.{Blake2b256, Sha256} import scorex.utils.Longs import sigma.Evaluation.stypeToRType -import sigma.ast.{AtLeast, EvaluatedValue, SType, SubstConstants, Value} +import sigma.ast.{AtLeast, BoxConstant, EvaluatedValue, SType, SubstConstants, Value} import sigma.crypto.{CryptoConstants, EcPointType, Ecp} import sigma.eval.Extensions.{EvalCollOps, toAnyValue} import sigma.exceptions.InvalidType @@ -16,7 +16,7 @@ import sigma.validation.SigmaValidationSettings import sigma.{AvlTree, BigInt, Box, Coll, CollBuilder, GroupElement, SigmaDslBuilder, SigmaProp, VersionContext} import java.math.BigInteger -import scala.reflect.ClassTag +import scala.reflect.{ClassTag, classTag} /** A default implementation of [[SigmaDslBuilder]] interface. * @@ -205,15 +205,14 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => } def deserialize[T](bytes: Coll[Byte])(implicit cT: RType[T]): T = { - if(!cT.isInstanceOf[PrimitiveType[_]]) { - throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: $cT") - } + val ba = bytes.toArray val res = cT.classTag match { - case ClassTag.Int => scorex.utils.Ints.fromByteArray(bytes.toArray) - case ClassTag.Long => scorex.utils.Longs.fromByteArray(bytes.toArray) + case ClassTag.Int => scorex.utils.Ints.fromByteArray(ba) + case ClassTag.Long => scorex.utils.Longs.fromByteArray(ba) + case sigma.data.BoxClassTag => CBox(ErgoBox.sigmaSerializer.fromBytes(ba)) case _ => - throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: $cT") + throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: ${cT.classTag}") } res.asInstanceOf[T] } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index a6630ee48c..235b422966 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -217,8 +217,22 @@ class BasicOpsSpecification extends CompilerTestingCommons } } - property("deserialize - box") { + property("deserialize - box rountrip") { + def deserTest() = test("deserialize", env, ext, + s"""{ + val b = INPUTS(0); + val ba = b.bytes; + Global.deserialize[Box](ba) == b + }""", + null, + true + ) + if (activatedVersionInTests < V6SoftForkVersion) { + an [sigma.exceptions.TyperException] should be thrownBy deserTest() + } else { + deserTest() + } } property("deserialize - bigint") { From fd589a8cf2447375b2e8028dc73cf7b49ceceac8 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 10 May 2024 18:26:45 +0300 Subject: [PATCH 18/25] bigInt test --- .../main/scala/sigma/data/CSigmaDslBuilder.scala | 9 ++++----- .../sigmastate/utxo/BasicOpsSpecification.scala | 13 +++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index 035fde1949..b89ac66c57 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -205,12 +205,11 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => } def deserialize[T](bytes: Coll[Byte])(implicit cT: RType[T]): T = { - val ba = bytes.toArray - val res = cT.classTag match { - case ClassTag.Int => scorex.utils.Ints.fromByteArray(ba) - case ClassTag.Long => scorex.utils.Longs.fromByteArray(ba) - case sigma.data.BoxClassTag => CBox(ErgoBox.sigmaSerializer.fromBytes(ba)) + case ClassTag.Int => scorex.utils.Ints.fromByteArray(bytes.toArray) + case ClassTag.Long => byteArrayToLong(bytes) + case sigma.data.BigIntClassTag => byteArrayToBigInt(bytes) + case sigma.data.BoxClassTag => CBox(ErgoBox.sigmaSerializer.fromBytes(bytes.toArray)) case _ => throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: ${cT.classTag}") } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 235b422966..9010855106 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -236,7 +236,20 @@ class BasicOpsSpecification extends CompilerTestingCommons } property("deserialize - bigint") { + def deserTest() = test("deserialize", env, ext, + s"""{ + val ba = fromBase16("028a5b7f7f7f7f7f7f6c"); + Global.deserialize[BigInt](ba) == byteArrayToBigInt(ba) + }""", + null, + true + ) + if (activatedVersionInTests < V6SoftForkVersion) { + an [sigma.exceptions.TyperException] should be thrownBy deserTest() + } else { + deserTest() + } } property("deserialize - header") { From 4404741275e9b2460c2962dc488a265df94d014c Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 10 May 2024 21:05:40 +0300 Subject: [PATCH 19/25] Short test --- .../scala/sigma/data/CSigmaDslBuilder.scala | 12 ++--- .../utxo/BasicOpsSpecification.scala | 44 +++++++++++++++++-- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index b89ac66c57..98de7ac69b 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -5,18 +5,18 @@ import org.ergoplatform.ErgoBox import org.ergoplatform.validation.ValidationRules import scorex.crypto.hash.{Blake2b256, Sha256} import scorex.utils.Longs -import sigma.Evaluation.stypeToRType -import sigma.ast.{AtLeast, BoxConstant, EvaluatedValue, SType, SubstConstants, Value} +import sigma.ast.{AtLeast, SubstConstants} import sigma.crypto.{CryptoConstants, EcPointType, Ecp} -import sigma.eval.Extensions.{EvalCollOps, toAnyValue} +import sigma.eval.Extensions.EvalCollOps import sigma.exceptions.InvalidType -import sigma.serialization.{GroupElementSerializer, SigmaSerializer, ValueSerializer} +import sigma.serialization.{GroupElementSerializer, SigmaSerializer} import sigma.util.Extensions.BigIntegerOps import sigma.validation.SigmaValidationSettings import sigma.{AvlTree, BigInt, Box, Coll, CollBuilder, GroupElement, SigmaDslBuilder, SigmaProp, VersionContext} import java.math.BigInteger -import scala.reflect.{ClassTag, classTag} +import java.nio.ByteBuffer +import scala.reflect.ClassTag /** A default implementation of [[SigmaDslBuilder]] interface. * @@ -205,7 +205,9 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => } def deserialize[T](bytes: Coll[Byte])(implicit cT: RType[T]): T = { + val res = cT.classTag match { + case ClassTag.Short => ByteBuffer.wrap(bytes.toArray).getShort case ClassTag.Int => scorex.utils.Ints.fromByteArray(bytes.toArray) case ClassTag.Long => byteArrayToLong(bytes) case sigma.data.BigIntClassTag => byteArrayToBigInt(bytes) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 9010855106..8f20bb0d69 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -3,7 +3,7 @@ package sigmastate.utxo import org.ergoplatform.ErgoBox.{AdditionalRegisters, R6, R8} import org.ergoplatform._ import scorex.util.encode.Base16 -import scorex.utils.Ints +import scorex.utils.{Ints, Shorts} import sigma.{Colls, SigmaProp} import sigma.Extensions.ArrayOps import sigma.VersionContext.V6SoftForkVersion @@ -252,14 +252,52 @@ class BasicOpsSpecification extends CompilerTestingCommons } } - property("deserialize - header") { + property("deserialize - short") { + val s = (-1925).toShort + def deserTest() = test("deserialize", env, ext, + s"""{ + val ba = fromBase16("${Base16.encode(Shorts.toByteArray(s))}"); + Global.deserialize[Short](ba) == -1925 + }""", + null, + true + ) + if (activatedVersionInTests < V6SoftForkVersion) { + an [sigma.exceptions.TyperException] should be thrownBy deserTest() + } else { + deserTest() + } } - property("deserialize - short") { + property("deserialize - group element") { + val s = (-1925).toShort + def deserTest() = test("deserialize", env, ext, + s"""{ + val ba = fromBase16("${Base16.encode(Shorts.toByteArray(s))}"); + Global.deserialize[Short](ba) == -1925 + }""", + null, + true + ) + if (activatedVersionInTests < V6SoftForkVersion) { + an [sigma.exceptions.TyperException] should be thrownBy deserTest() + } else { + deserTest() + } } + property("deserialize - avltree") { + + } + + property("deserialize - header") { + + } + + + /* property("getVar") { From 7d69ebc55651d19cea2232763bb92660f219c287 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 10 May 2024 21:18:33 +0300 Subject: [PATCH 20/25] group elem impl & test --- .../main/scala/sigma/data/CSigmaDslBuilder.scala | 1 + .../sigmastate/utxo/BasicOpsSpecification.scala | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index 98de7ac69b..d57533d492 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -212,6 +212,7 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => case ClassTag.Long => byteArrayToLong(bytes) case sigma.data.BigIntClassTag => byteArrayToBigInt(bytes) case sigma.data.BoxClassTag => CBox(ErgoBox.sigmaSerializer.fromBytes(bytes.toArray)) + case sigma.data.GroupElementClassTag => CGroupElement(GroupElementSerializer.fromBytes(bytes.toArray)) case _ => throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: ${cT.classTag}") } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 8f20bb0d69..dd226bfb4a 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -24,6 +24,7 @@ import sigma.ast.Apply import sigma.eval.EvalSettings import sigma.exceptions.InvalidType import sigma.serialization.ValueSerializer +import sigmastate.utils.Helpers import sigmastate.utils.Helpers._ import java.math.BigInteger @@ -271,18 +272,21 @@ class BasicOpsSpecification extends CompilerTestingCommons } property("deserialize - group element") { - val s = (-1925).toShort - def deserTest() = test("deserialize", env, ext, + val ge = Helpers.decodeGroupElement("026930cb9972e01534918a6f6d6b8e35bc398f57140d13eb3623ea31fbd069939b") + val ba = Base16.encode(ge.getEncoded.toArray) + def deserTest() = test("deserialize", env, Seq(21.toByte -> GroupElementConstant(ge)), s"""{ - val ba = fromBase16("${Base16.encode(Shorts.toByteArray(s))}"); - Global.deserialize[Short](ba) == -1925 + val ge = getVar[GroupElement](21).get + val ba = fromBase16("$ba"); + val ge2 = Global.deserialize[GroupElement](ba) + ba == ge2.getEncoded && ge == ge2 }""", null, true ) if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() + an [sigma.exceptions.TyperException] should be thrownBy deserTest() } else { deserTest() } From 48f112a3abbfb124b591483cdd242d3a8badc536 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Sun, 12 May 2024 20:03:30 +0300 Subject: [PATCH 21/25] sigmaprop test & impl --- .../scala/sigma/data/CSigmaDslBuilder.scala | 10 +++- .../utxo/BasicOpsSpecification.scala | 47 +++++++++++++------ 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index d57533d492..db2c0c8869 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -5,11 +5,11 @@ import org.ergoplatform.ErgoBox import org.ergoplatform.validation.ValidationRules import scorex.crypto.hash.{Blake2b256, Sha256} import scorex.utils.Longs -import sigma.ast.{AtLeast, SubstConstants} +import sigma.ast.{AtLeast, EvaluatedValue, SigmaPropConstant, SubstConstants} import sigma.crypto.{CryptoConstants, EcPointType, Ecp} import sigma.eval.Extensions.EvalCollOps import sigma.exceptions.InvalidType -import sigma.serialization.{GroupElementSerializer, SigmaSerializer} +import sigma.serialization.{ErgoTreeSerializer, GroupElementSerializer, SigmaSerializer} import sigma.util.Extensions.BigIntegerOps import sigma.validation.SigmaValidationSettings import sigma.{AvlTree, BigInt, Box, Coll, CollBuilder, GroupElement, SigmaDslBuilder, SigmaProp, VersionContext} @@ -213,6 +213,12 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => case sigma.data.BigIntClassTag => byteArrayToBigInt(bytes) case sigma.data.BoxClassTag => CBox(ErgoBox.sigmaSerializer.fromBytes(bytes.toArray)) case sigma.data.GroupElementClassTag => CGroupElement(GroupElementSerializer.fromBytes(bytes.toArray)) + case sigma.data.SigmaPropClassTag => + //todo : better exception, check for isInstance [EvaluatedValue[_]] + ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes.toArray).root match { + case Left(_) => throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: ${cT.classTag}") + case Right(prop) => prop.asInstanceOf[EvaluatedValue[_]].value + } case _ => throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: ${cT.classTag}") } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index dd226bfb4a..4303ccb655 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -9,7 +9,7 @@ import sigma.Extensions.ArrayOps import sigma.VersionContext.V6SoftForkVersion import sigma.ast.SCollection.SByteArray import sigma.ast.SType.AnyOps -import sigma.data.{AvlTreeData, CAnyValue, CSigmaDslBuilder, ProveDlog} +import sigma.data.{AvlTreeData, CAND, CAnyValue, CSigmaDslBuilder, CSigmaProp, ProveDlog} import sigma.util.StringUtil._ import sigma.ast._ import sigma.ast.syntax._ @@ -48,7 +48,9 @@ class BasicOpsSpecification extends CompilerTestingCommons val booleanVar = 9.toByte val propVar1 = 10.toByte val propVar2 = 11.toByte - val lastExtVar = propVar2 + val propVar3 = 12.toByte + val propBytesVar1 = 13.toByte + val lastExtVar = propBytesVar1 val ext: Seq[VarBinding] = Seq( (intVar1, IntConstant(1)), (intVar2, IntConstant(2)), @@ -77,7 +79,14 @@ class BasicOpsSpecification extends CompilerTestingCommons override lazy val contextExtenders: Map[Byte, EvaluatedValue[_ <: SType]] = { val p1 = dlogSecrets(0).publicImage val p2 = dlogSecrets(1).publicImage - (ext ++ Seq(propVar1 -> SigmaPropConstant(p1), propVar2 -> SigmaPropConstant(p2))).toMap + val d1 = dhSecrets(0).publicImage + + (ext ++ Seq( + propVar1 -> SigmaPropConstant(p1), + propVar2 -> SigmaPropConstant(p2), + propVar3 -> SigmaPropConstant(CSigmaProp(CAND(Seq(p1, d1)))), + propBytesVar1 -> ByteArrayConstant(CSigmaProp(CAND(Seq(p1, d1))).propBytes) + )).toMap } override val evalSettings: EvalSettings = DefaultEvalSettings.copy( isMeasureOperationTime = true, @@ -240,7 +249,8 @@ class BasicOpsSpecification extends CompilerTestingCommons def deserTest() = test("deserialize", env, ext, s"""{ val ba = fromBase16("028a5b7f7f7f7f7f7f6c"); - Global.deserialize[BigInt](ba) == byteArrayToBigInt(ba) + val b = Global.deserialize[BigInt](ba) + b == byteArrayToBigInt(ba) }""", null, true @@ -292,25 +302,34 @@ class BasicOpsSpecification extends CompilerTestingCommons } } - property("deserialize - avltree") { + property("deserialize - sigmaprop roundtrip") { + + def deserTest() = test("deserialize", env, ext, + s"""{ + val ba = getVar[Coll[Byte]]($propBytesVar1).get + val prop = Global.deserialize[SigmaProp](ba) + prop == getVar[SigmaProp]($propVar3).get && prop + }""", + null, + true + ) + if (activatedVersionInTests < V6SoftForkVersion) { + an [sigma.exceptions.TyperException] should be thrownBy deserTest() + } else { + deserTest() + } } - property("deserialize - header") { + property("deserialize - avltree") { } + property("deserialize - header") { + } - /* - property("getVar") { - test("getVar", env, ext, - "{ allOf(Coll(CONTEXT.getVar[Boolean](trueVar).get, true, true)) }", - AND(GetVarBoolean(booleanVar).get, TrueLeaf, TrueLeaf).toSigmaProp - ) - } */ - property("executeFromVar - SigmaProp") { val script = GT(Height, IntConstant(-1)).toSigmaProp val scriptBytes = ValueSerializer.serialize(script) From 63f8cccedddcb71c4251655919ce7530312fb8e6 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Sun, 12 May 2024 20:24:12 +0300 Subject: [PATCH 22/25] non evaluated sigmaprop test --- .../scala/sigma/data/CSigmaDslBuilder.scala | 9 +++++-- .../utxo/BasicOpsSpecification.scala | 25 ++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index db2c0c8869..faf995c810 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -216,8 +216,13 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => case sigma.data.SigmaPropClassTag => //todo : better exception, check for isInstance [EvaluatedValue[_]] ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes.toArray).root match { - case Left(_) => throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: ${cT.classTag}") - case Right(prop) => prop.asInstanceOf[EvaluatedValue[_]].value + case Left(_) => throw new InvalidType(s"Cannot deserialize($bytes): unparsed tree provided") + case Right(prop) => + if(prop.isInstanceOf[EvaluatedValue[_]]) { + prop.asInstanceOf[EvaluatedValue[_]].value + } else { + throw new InvalidType(s"Cannot deserialize($bytes): prop is not evaluated: $prop}") + } } case _ => throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: ${cT.classTag}") diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 4303ccb655..c470f946e6 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -23,7 +23,7 @@ import sigmastate.interpreter.Interpreter._ import sigma.ast.Apply import sigma.eval.EvalSettings import sigma.exceptions.InvalidType -import sigma.serialization.ValueSerializer +import sigma.serialization.{ErgoTreeSerializer, ValueSerializer} import sigmastate.utils.Helpers import sigmastate.utils.Helpers._ @@ -321,6 +321,29 @@ class BasicOpsSpecification extends CompilerTestingCommons } } + property("deserialize - sigmaprop roundtrip - non evaluated") { + + val script = GT(Height, IntConstant(-1)).toSigmaProp + val scriptBytes = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(ErgoTree.fromProposition(script)) + val customExt = Seq(21.toByte -> ByteArrayConstant(scriptBytes)) + + def deserTest() = test("deserialize", env, customExt, + s"""{ + val ba = getVar[Coll[Byte]](21).get + val prop = Global.deserialize[SigmaProp](ba) + prop + }""", + null, + true + ) + + if (activatedVersionInTests < V6SoftForkVersion) { + an [sigma.exceptions.TyperException] should be thrownBy deserTest() + } else { + an [Exception] should be thrownBy deserTest() + } + } + property("deserialize - avltree") { } From 516f05d3e09248a4ff5549203538096971790909 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Sun, 12 May 2024 20:40:11 +0300 Subject: [PATCH 23/25] avltree test & impl --- .../scala/sigma/data/CSigmaDslBuilder.scala | 5 +++- .../utxo/BasicOpsSpecification.scala | 27 +++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index faf995c810..0f63b98b33 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -214,7 +214,6 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => case sigma.data.BoxClassTag => CBox(ErgoBox.sigmaSerializer.fromBytes(bytes.toArray)) case sigma.data.GroupElementClassTag => CGroupElement(GroupElementSerializer.fromBytes(bytes.toArray)) case sigma.data.SigmaPropClassTag => - //todo : better exception, check for isInstance [EvaluatedValue[_]] ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes.toArray).root match { case Left(_) => throw new InvalidType(s"Cannot deserialize($bytes): unparsed tree provided") case Right(prop) => @@ -224,6 +223,10 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => throw new InvalidType(s"Cannot deserialize($bytes): prop is not evaluated: $prop}") } } + case sigma.data.AvlTreeClassTag => + CAvlTree(AvlTreeData.serializer.fromBytes(bytes.toArray)) + case sigma.data.HeaderClassTag => + // todo: add header case _ => throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: ${cT.classTag}") } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index c470f946e6..7ef5c080dc 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -2,14 +2,17 @@ package sigmastate.utxo import org.ergoplatform.ErgoBox.{AdditionalRegisters, R6, R8} import org.ergoplatform._ +import scorex.crypto.authds.{ADKey, ADValue} +import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert} +import scorex.crypto.hash.{Blake2b256, Digest32} import scorex.util.encode.Base16 -import scorex.utils.{Ints, Shorts} +import scorex.utils.{Ints, Longs, Shorts} import sigma.{Colls, SigmaProp} import sigma.Extensions.ArrayOps import sigma.VersionContext.V6SoftForkVersion import sigma.ast.SCollection.SByteArray import sigma.ast.SType.AnyOps -import sigma.data.{AvlTreeData, CAND, CAnyValue, CSigmaDslBuilder, CSigmaProp, ProveDlog} +import sigma.data.{AvlTreeClassTag, AvlTreeData, AvlTreeFlags, CAND, CAnyValue, CSigmaDslBuilder, CSigmaProp, ProveDlog} import sigma.util.StringUtil._ import sigma.ast._ import sigma.ast.syntax._ @@ -345,7 +348,27 @@ class BasicOpsSpecification extends CompilerTestingCommons } property("deserialize - avltree") { + val elements = Seq(123, 22) + val treeElements = elements.map(i => Longs.toByteArray(i)).map(s => (ADKey @@@ Blake2b256(s), ADValue @@ s)) + val avlProver = new BatchAVLProver[Digest32, Blake2b256.type](keyLength = 32, None) + treeElements.foreach(s => avlProver.performOneOperation(Insert(s._1, s._2))) + avlProver.generateProof() + val treeData = new AvlTreeData(avlProver.digest.toColl, AvlTreeFlags.ReadOnly, 32, None) + val treeBytes = AvlTreeData.serializer.toBytes(treeData) + val customExt = Seq(21.toByte -> ByteArrayConstant(treeBytes)) + + def deserTest() = test("deserialize", env, customExt, + s"""{ + val ba = getVar[Coll[Byte]](21).get + val tree = Global.deserialize[AvlTree](ba) + tree.digest == fromBase16(${Base16.encode(treeData.digest.toArray)}) && tree.enabledOperations == 0 + }""", + null, + true + ) + + an [Exception] should be thrownBy deserTest() } property("deserialize - header") { From 9b2d56ee84b1133638a978c55167bece990bb478 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Mon, 13 May 2024 12:55:26 +0300 Subject: [PATCH 24/25] removing 6.0 related code --- README.md | 2 +- .../src/main/scala/sigma/SigmaDsl.scala | 2 - .../src/main/scala/sigma/VersionContext.scala | 18 +- .../sigma/reflection/ReflectionData.scala | 3 - .../src/test/scala/sigma/VersionTesting.scala | 11 +- .../src/main/scala/sigma/ast/methods.scala | 76 ++---- .../scala/sigma/data/CSigmaDslBuilder.scala | 36 +-- .../serialization/MethodCallSerializer.scala | 16 +- .../MethodCallSerializerSpecification.scala | 24 -- .../scala/sigmastate/eval/GraphBuilding.scala | 31 +-- .../scala/sigmastate/eval/TreeBuilding.scala | 7 +- .../scala/sigmastate/lang/SigmaTyper.scala | 14 -- .../scala/special/sigma/SigmaDslUnit.scala | 1 - .../special/sigma/impl/SigmaDslImpl.scala | 28 +-- .../scala/sigmastate/CompilerTestsBase.scala | 2 +- .../utxo/BasicOpsSpecification.scala | 232 +----------------- 16 files changed, 41 insertions(+), 462 deletions(-) diff --git a/README.md b/README.md index 411c502dd2..6003daf55a 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ This library is on Maven repository and can be added to the SBT configuration of Scala project. ```scala -libraryDependencies += "org.scorexfoundation" %% "sigma-state" % "6.0.0" +libraryDependencies += "org.scorexfoundation" %% "sigma-state" % "5.0.14" ``` ## Repository Organization diff --git a/core/shared/src/main/scala/sigma/SigmaDsl.scala b/core/shared/src/main/scala/sigma/SigmaDsl.scala index 29142a624c..df2b419273 100644 --- a/core/shared/src/main/scala/sigma/SigmaDsl.scala +++ b/core/shared/src/main/scala/sigma/SigmaDsl.scala @@ -729,7 +729,5 @@ trait SigmaDslBuilder { /** Returns a byte-wise XOR of the two collections of bytes. */ def xor(l: Coll[Byte], r: Coll[Byte]): Coll[Byte] - - def deserialize[T](bytes: Coll[Byte])(implicit cT: RType[T]): T } diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 19a4857086..67b7079fea 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -1,6 +1,6 @@ package sigma -import VersionContext.{JitActivationVersion, V6SoftForkVersion} +import VersionContext.JitActivationVersion import scala.util.DynamicVariable @@ -21,10 +21,6 @@ case class VersionContext(activatedVersion: Byte, ergoTreeVersion: Byte) { /** @return true, if the activated script version of Ergo protocol on the network is * greater than v1. */ def isJitActivated: Boolean = activatedVersion >= JitActivationVersion - - /** @return true, if the activated script version of Ergo protocol on the network is - * including Evolution update. */ - def isV6SoftForkActivated: Boolean = activatedVersion >= V6SoftForkVersion } object VersionContext { @@ -35,21 +31,13 @@ object VersionContext { * - version 3.x this value must be 0 * - in v4.0 must be 1 * - in v5.x must be 2 - * - in 6.x must be 3 * etc. */ - val MaxSupportedScriptVersion: Byte = 3 // supported versions 0, 1, 2, 3 + val MaxSupportedScriptVersion: Byte = 2 // supported versions 0, 1, 2 - /** The first version of ErgoTree starting from which the JIT costing interpreter must be used. - * It must also be used for all subsequent versions (3, 4, etc). - */ + /** The first version of ErgoTree starting from which the JIT costing interpreter is used. */ val JitActivationVersion: Byte = 2 - /** - * The version of ErgoTree corresponding to "evolution" (6.0) soft-fork - */ - val V6SoftForkVersion: Byte = 3 - private val _defaultContext = VersionContext( activatedVersion = 1 /* v4.x */, ergoTreeVersion = 1 diff --git a/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala b/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala index cecc0f91bd..028e68bf72 100644 --- a/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala +++ b/core/shared/src/main/scala/sigma/reflection/ReflectionData.scala @@ -443,9 +443,6 @@ object ReflectionData { }, mkMethod(clazz, "decodePoint", Array[Class[_]](cColl)) { (obj, args) => obj.asInstanceOf[SigmaDslBuilder].decodePoint(args(0).asInstanceOf[Coll[Byte]]) - }, - mkMethod(clazz, "deserialize", Array[Class[_]](cColl, classOf[RType[_]])) { (obj, args) => - obj.asInstanceOf[SigmaDslBuilder].deserialize(args(0).asInstanceOf[Coll[Byte]])(args(1).asInstanceOf[RType[_]]) } ) ) diff --git a/core/shared/src/test/scala/sigma/VersionTesting.scala b/core/shared/src/test/scala/sigma/VersionTesting.scala index 69e15ff491..a17fc7a7f9 100644 --- a/core/shared/src/test/scala/sigma/VersionTesting.scala +++ b/core/shared/src/test/scala/sigma/VersionTesting.scala @@ -6,11 +6,13 @@ import scala.util.DynamicVariable trait VersionTesting { - /** Tests run for both version 2 & version 3 */ + /** In v5.x we run test for only one activated version on the network (== 2). + * In the branch for v6.0 the new version 3 should be added so that the tests run for both. + */ protected val activatedVersions: Seq[Byte] = (0 to VersionContext.MaxSupportedScriptVersion).map(_.toByte).toArray[Byte] - private[sigma] val _currActivatedVersion = new DynamicVariable[Byte](3) // v6.x by default + private[sigma] val _currActivatedVersion = new DynamicVariable[Byte](2) // v5.x by default /** Current activated version used in tests. */ def activatedVersionInTests: Byte = _currActivatedVersion.value @@ -39,10 +41,9 @@ trait VersionTesting { _ + 1) { j => val treeVersion = ergoTreeVers(j) // for each tree version up to currently activated, set it up and execute block - _currErgoTreeVersion.withValue(treeVersion) { - VersionContext.withVersions(activatedVersion, treeVersion)(block) - } + _currErgoTreeVersion.withValue(treeVersion)(block) } + } } } diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index e948346868..3b7368c542 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -2,11 +2,10 @@ package sigma.ast import org.ergoplatform._ import org.ergoplatform.validation._ -import sigma.Evaluation.stypeToRType import sigma._ import sigma.ast.SCollection.{SBooleanArray, SBoxArray, SByteArray, SByteArray2, SHeaderArray} import sigma.ast.SMethod.{MethodCallIrBuilder, MethodCostFunc, javaMethodOf} -import sigma.ast.SType.{TypeCode, paramT, tT} +import sigma.ast.SType.TypeCode import sigma.ast.syntax.{SValue, ValueOps} import sigma.data.OverloadHack.Overloaded1 import sigma.data.{DataValueComparer, KeyValueColl, Nullable, RType, SigmaConstants} @@ -53,7 +52,7 @@ sealed trait MethodsContainer { protected def getMethods(): Seq[SMethod] = Nil /** Returns all the methods of this type. */ - def methods: Seq[SMethod] = { //todo: consider versioned caching + lazy val methods: Seq[SMethod] = { val ms = getMethods().toArray assert(ms.map(_.name).distinct.length == ms.length, s"Duplicate method names in $this") ms.groupBy(_.objType).foreach { case (comp, ms) => @@ -61,7 +60,7 @@ sealed trait MethodsContainer { } ms } - private def _methodsMap: Map[Byte, Map[Byte, SMethod]] = methods //todo: consider versioned caching + private lazy val _methodsMap: Map[Byte, Map[Byte, SMethod]] = methods .groupBy(_.objType.typeId) .map { case (typeId, ms) => (typeId -> ms.map(m => m.methodId -> m).toMap) } @@ -310,13 +309,6 @@ case object SBigIntMethods extends SNumericTypeMethods { /** Type for which this container defines methods. */ override def ownerType: SMonoType = SBigInt - final val ToNBitsCostInfo = OperationCostInfo( - FixedCost(JitCost(5)), NamedDesc("NBitsMethodCall")) - - //id = 8 to make it after toBits - val ToNBits = SMethod(this, "nbits", SFunc(this.ownerType, SLong), 8, ToNBitsCostInfo.costKind) - .withInfo(ModQ, "Encode this big integer value as NBits") - /** The following `modQ` methods are not fully implemented in v4.x and this descriptors. * This descritors are remain here in the code and are waiting for full implementation * is upcoming soft-forks at which point the cost parameters should be calculated and @@ -332,26 +324,13 @@ case object SBigIntMethods extends SNumericTypeMethods { .withIRInfo(MethodCallIrBuilder) .withInfo(MethodCall, "Multiply this number with \\lst{other} by module Q.", ArgInfo("other", "Number to multiply with this.")) - protected override def getMethods(): Seq[SMethod] = { - if (VersionContext.current.isV6SoftForkActivated) { - super.getMethods() ++ Seq(ToNBits) - // ModQMethod, - // PlusModQMethod, - // MinusModQMethod, - // TODO soft-fork: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/479 - // MultModQMethod, - } else { - super.getMethods() - } - } - - /** - * - */ - def nbits_eval(mc: MethodCall, bi: sigma.BigInt)(implicit E: ErgoTreeEvaluator): Long = { - ??? - } - + protected override def getMethods() = super.getMethods() ++ Seq( +// ModQMethod, +// PlusModQMethod, +// MinusModQMethod, + // TODO soft-fork: https://github.com/ScorexFoundation/sigmastate-interpreter/issues/479 + // MultModQMethod, + ) } /** Methods of type `String`. */ @@ -1511,14 +1490,6 @@ case object SGlobalMethods extends MonoTypeMethods { .withInfo(Xor, "Byte-wise XOR of two collections of bytes", ArgInfo("left", "left operand"), ArgInfo("right", "right operand")) - lazy val desJava = ownerType.reprClass.getMethod("deserialize", classOf[Coll[Byte]], classOf[RType[_]]) - - lazy val deserializeMethod = SMethod( - this, "deserialize", SFunc(Array(SGlobal, SByteArray), tT, Array(paramT)), 3, Xor.costKind) // todo: cost - .copy(irInfo = MethodIRInfo(None, Some(desJava), None)) - .withInfo(Xor, "Byte-wise XOR of two collections of bytes", - ArgInfo("left", "left operand"), ArgInfo("right", "right operand")) - /** Implements evaluation of Global.xor method call ErgoTree node. * Called via reflection based on naming convention. * @see SMethod.evalMethod, Xor.eval, Xor.xorWithCosting @@ -1528,28 +1499,9 @@ case object SGlobalMethods extends MonoTypeMethods { Xor.xorWithCosting(ls, rs) } - - def deserialize_eval(mc: MethodCall, G: SigmaDslBuilder, bytes: Coll[Byte]) - (implicit E: ErgoTreeEvaluator): Any = { - val cT = stypeToRType(mc.tpe) - E.addSeqCost(Xor.costKind, bytes.length, Xor.opDesc) { () => // todo: cost - G.deserialize(bytes)(cT) - } - } - - protected override def getMethods() = super.getMethods() ++ { - if (VersionContext.current.isV6SoftForkActivated) { - Seq( - groupGeneratorMethod, - xorMethod, - deserializeMethod - ) - } else { - Seq( - groupGeneratorMethod, - xorMethod - ) - } - } + protected override def getMethods() = super.getMethods() ++ Seq( + groupGeneratorMethod, + xorMethod + ) } diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index 0f63b98b33..3938feacd3 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -5,18 +5,15 @@ import org.ergoplatform.ErgoBox import org.ergoplatform.validation.ValidationRules import scorex.crypto.hash.{Blake2b256, Sha256} import scorex.utils.Longs -import sigma.ast.{AtLeast, EvaluatedValue, SigmaPropConstant, SubstConstants} +import sigma.ast.{AtLeast, SubstConstants} import sigma.crypto.{CryptoConstants, EcPointType, Ecp} import sigma.eval.Extensions.EvalCollOps -import sigma.exceptions.InvalidType -import sigma.serialization.{ErgoTreeSerializer, GroupElementSerializer, SigmaSerializer} +import sigma.serialization.{GroupElementSerializer, SigmaSerializer} import sigma.util.Extensions.BigIntegerOps import sigma.validation.SigmaValidationSettings import sigma.{AvlTree, BigInt, Box, Coll, CollBuilder, GroupElement, SigmaDslBuilder, SigmaProp, VersionContext} import java.math.BigInteger -import java.nio.ByteBuffer -import scala.reflect.ClassTag /** A default implementation of [[SigmaDslBuilder]] interface. * @@ -203,35 +200,6 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => val p = GroupElementSerializer.parse(r) this.GroupElement(p) } - - def deserialize[T](bytes: Coll[Byte])(implicit cT: RType[T]): T = { - - val res = cT.classTag match { - case ClassTag.Short => ByteBuffer.wrap(bytes.toArray).getShort - case ClassTag.Int => scorex.utils.Ints.fromByteArray(bytes.toArray) - case ClassTag.Long => byteArrayToLong(bytes) - case sigma.data.BigIntClassTag => byteArrayToBigInt(bytes) - case sigma.data.BoxClassTag => CBox(ErgoBox.sigmaSerializer.fromBytes(bytes.toArray)) - case sigma.data.GroupElementClassTag => CGroupElement(GroupElementSerializer.fromBytes(bytes.toArray)) - case sigma.data.SigmaPropClassTag => - ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes.toArray).root match { - case Left(_) => throw new InvalidType(s"Cannot deserialize($bytes): unparsed tree provided") - case Right(prop) => - if(prop.isInstanceOf[EvaluatedValue[_]]) { - prop.asInstanceOf[EvaluatedValue[_]].value - } else { - throw new InvalidType(s"Cannot deserialize($bytes): prop is not evaluated: $prop}") - } - } - case sigma.data.AvlTreeClassTag => - CAvlTree(AvlTreeData.serializer.fromBytes(bytes.toArray)) - case sigma.data.HeaderClassTag => - // todo: add header - case _ => - throw new InvalidType(s"Cannot deserialize($bytes): invalid type of value: ${cT.classTag}") - } - res.asInstanceOf[T] - } } /** Default singleton instance of Global object, which implements global ErgoTree functions. */ diff --git a/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala b/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala index 693e66d57e..319a4284e2 100644 --- a/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/MethodCallSerializer.scala @@ -1,12 +1,11 @@ package sigma.serialization import sigma.ast.syntax._ -import sigma.ast.{MethodCall, SContextMethods, SGlobalMethods, SMethod, SType, STypeSubst, Value, ValueCompanion} +import sigma.ast.{MethodCall, SContextMethods, SMethod, SType, STypeSubst, Value, ValueCompanion} import sigma.util.safeNewArray import SigmaByteWriter._ import debox.cfor import sigma.ast.SContextMethods.BlockchainContextMethodNames -import sigma.ast.SType.tT import sigma.serialization.CoreByteWriter.{ArgInfo, DataInfo} case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[SType]], STypeSubst) => Value[SType]) @@ -16,7 +15,6 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S val methodCodeInfo: DataInfo[Byte] = ArgInfo("methodCode", "a code of the method") val objInfo: DataInfo[SValue] = ArgInfo("obj", "receiver object of this method call") val argsInfo: DataInfo[Seq[SValue]] = ArgInfo("args", "arguments of the method call") - val typeInfo: DataInfo[SType] = ArgInfo("type", "expected type of method result") val argsItemInfo = valuesItemInfo(argsInfo) override def serialize(mc: MethodCall, w: SigmaByteWriter): Unit = { @@ -25,9 +23,6 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S w.putValue(mc.obj, objInfo) assert(mc.args.nonEmpty) w.putValues(mc.args, argsInfo, argsItemInfo) - if(mc.method.name == SGlobalMethods.deserializeMethod.name){ - w.putType(mc.tpe, typeInfo) - } } /** The SMethod instances in STypeCompanions may have type STypeIdent in methods types, @@ -62,17 +57,10 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S val specMethod = method.specializeFor(obj.tpe, types) - val subst: STypeSubst = if(method.name == SGlobalMethods.deserializeMethod.name) { - val tpe = r.getType() - Map(tT -> tpe) - } else { - Map.empty - } - var isUsingBlockchainContext = specMethod.objType == SContextMethods && BlockchainContextMethodNames.contains(method.name) r.wasUsingBlockchainContext ||= isUsingBlockchainContext - cons(obj, specMethod, args, subst) + cons(obj, specMethod, args, Map.empty) } } diff --git a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala index 1db166c685..ac9c997d98 100644 --- a/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala +++ b/interpreter/shared/src/test/scala/sigma/serialization/MethodCallSerializerSpecification.scala @@ -1,8 +1,6 @@ package sigma.serialization -import sigma.VersionContext import sigma.ast._ -import sigma.validation.ValidationException class MethodCallSerializerSpecification extends SerializationSpecification { @@ -23,26 +21,4 @@ class MethodCallSerializerSpecification extends SerializationSpecification { ) roundTripTest(expr) } - - property("MethodCall deserialization round trip for BigInt.nbits") { - def code = { - val bi = BigIntConstant(5) - val expr = MethodCall(bi, - SBigIntMethods.ToNBits, - Vector(), - Map() - ) - roundTripTest(expr) - } - - VersionContext.withVersions(VersionContext.V6SoftForkVersion, 1) { - code - } - - an[ValidationException] should be thrownBy ( - VersionContext.withVersions((VersionContext.V6SoftForkVersion - 1).toByte, 1) { - code - } - ) - } } diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index ef78790db7..96b7c76824 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala @@ -2,8 +2,7 @@ package sigmastate.eval import org.ergoplatform._ import scalan.MutableLazy -import sigma.ast.SCollection.SByteArray -import sigma.{SigmaException, VersionContext, ast} +import sigma.{SigmaException, ast} import sigma.ast.TypeCodes.LastConstantCode import sigma.ast.Value.Typed import sigma.ast._ @@ -20,25 +19,6 @@ import sigma.serialization.OpCodes import scala.collection.mutable.ArrayBuffer - -case class DeserializeBytes[V <: SType](bytes: Value[SByteArray], tpe: V) extends NotReadyValue[V] { - /** The companion node descriptor with opCode, cost and other metadata. */ - override def companion: ValueCompanion = ??? - - /** Every value represents an operation and that operation can be associated with a function type, - * describing functional meaning of the operation, kind of operation signature. - * Thus, we can obtain global operation identifiers by combining Value.opName with Value.opType, - * so that if (v1.opName == v2.opName) && (v1.opType == v2.opType) then v1 and v2 are functionally - * point-wise equivalent. - * This in particular means that if two _different_ ops have the same opType they _should_ have - * different opNames. - * Thus defined op ids are used in a v4.x Cost Model - a table of all existing primitives coupled with - * performance parameters. - * */ - override def opType: SFunc = Value.notSupportedError(this, "opType") -} - - /** Perform translation of typed expression given by [[Value]] to a graph in IRContext. * Which be than be translated to [[ErgoTree]] by using [[TreeBuilding]]. * @@ -556,9 +536,6 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => val e = stypeToElem(optTpe.elemType) ctx.getVar(id)(e) - case DeserializeBytes(bytes, tpe) => - sigmaDslBuilder.deserialize(asRep[Coll[Byte]](eval(bytes)))(stypeToElem(tpe)) - case d: DeserializeContext[T] => val e = stypeToElem(d.tpe).asInstanceOf[Elem[T]] DeserializeContextDef(d, e) @@ -942,7 +919,7 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => sigmaDslBuilder.decodePoint(bytes) // fallback rule for MethodCall, should be the last case in the list - case sigma.ast.MethodCall(obj, method, args, typeSubst) => + case sigma.ast.MethodCall(obj, method, args, _) => val objV = eval(obj) val argsV = args.map(eval) (objV, method.objType) match { @@ -1160,10 +1137,6 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => val c1 = asRep[Coll[Byte]](argsV(0)) val c2 = asRep[Coll[Byte]](argsV(1)) g.xor(c1, c2) - case SGlobalMethods.deserializeMethod.name if VersionContext.current.isV6SoftForkActivated => - val c1 = asRep[Coll[Byte]](argsV(0)) - val c2 = stypeToElem(method.stype.tRange.withSubstTypes(typeSubst)) - g.deserialize(c1)(c2) case _ => throwError } case _ => throwError diff --git a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala index 2071e7b0d1..22ffe0ae94 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -3,7 +3,6 @@ package sigmastate.eval import sigma.ast._ import org.ergoplatform._ -import sigma.ast.SType.tT import sigma.ast.syntax.ValueOps import sigma.serialization.OpCodes._ import sigma.serialization.ConstantStore @@ -222,10 +221,6 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => val tpe = elemToSType(eVar) mkGetVar(id, tpe) - case SDBM.deserialize(g, bytes, eVar) => - val tpe = elemToSType(eVar) - builder.mkMethodCall(recurse(g), SGlobalMethods.deserializeMethod, IndexedSeq(recurse(bytes)), Map(tT -> tpe): STypeSubst) - case BIM.subtract(In(x), In(y)) => mkArith(x.asNumValue, y.asNumValue, MinusCode) case BIM.add(In(x), In(y)) => @@ -411,7 +406,7 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext => MethodsContainer.getMethod(obj.tpe, m.getName) match { case Some(method) => val specMethod = method.specializeFor(obj.tpe, args.map(_.tpe)) - builder.mkMethodCall(obj, specMethod, args.toIndexedSeq, Map.empty) + builder.mkMethodCall(obj, specMethod, args.toIndexedSeq, Map()) case None => error(s"Cannot find method ${m.getName} in object $obj") } diff --git a/sc/shared/src/main/scala/sigmastate/lang/SigmaTyper.scala b/sc/shared/src/main/scala/sigmastate/lang/SigmaTyper.scala index 991b3ce064..9c65c14aea 100644 --- a/sc/shared/src/main/scala/sigmastate/lang/SigmaTyper.scala +++ b/sc/shared/src/main/scala/sigmastate/lang/SigmaTyper.scala @@ -10,7 +10,6 @@ import SigmaPredef._ import sigma.ast.syntax._ import sigma.exceptions.TyperException import sigma.serialization.OpCodes -import sigmastate.eval.DeserializeBytes import scala.collection.mutable.ArrayBuffer @@ -133,19 +132,6 @@ class SigmaTyper(val builder: SigmaBuilder, val newObj = assignType(env, obj) val newArgs = args.map(assignType(env, _)) obj.tpe match { - case SGlobal => - SGlobalMethods.method(n) match { - case Some(method) => - val srcCtx = sel.sourceContext - if(method.name == SGlobalMethods.deserializeMethod.name) { - val global = Global.withPropagatedSrcCtx(srcCtx) - DeserializeBytes(args(0).asInstanceOf[Value[SByteArray]], rangeTpe) - } else { - processGlobalMethod(srcCtx, method, newArgs) - } - case _ => - error(s"Cannot find Global method: $n", bound.sourceContext) - } case p: SProduct => MethodsContainer.getMethod(p, n) match { case Some(method @ SMethod(_, _, genFunTpe @ SFunc(_, _, _), _, _, _, _, _)) => diff --git a/sc/shared/src/main/scala/special/sigma/SigmaDslUnit.scala b/sc/shared/src/main/scala/special/sigma/SigmaDslUnit.scala index 26addccf8d..48548226a5 100644 --- a/sc/shared/src/main/scala/special/sigma/SigmaDslUnit.scala +++ b/sc/shared/src/main/scala/special/sigma/SigmaDslUnit.scala @@ -112,7 +112,6 @@ package sigma { /** This method will be used in v6.0 to handle CreateAvlTree operation in GraphBuilding */ def avlTree(operationFlags: Ref[Byte], digest: Ref[Coll[Byte]], keyLength: Ref[Int], valueLengthOpt: Ref[WOption[Int]]): Ref[AvlTree]; def xor(l: Ref[Coll[Byte]], r: Ref[Coll[Byte]]): Ref[Coll[Byte]] - def deserialize[T](bytes: Ref[Coll[Byte]])(implicit cT: Elem[T]): Ref[T] }; trait CostModelCompanion; trait BigIntCompanion; diff --git a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala index efdb3dbda0..70fb35c329 100644 --- a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -1941,13 +1941,6 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { Array[AnyRef](l, r), true, false, element[Coll[Byte]])) } - - override def deserialize[T](l: Ref[Coll[Byte]])(implicit cT: Elem[T]): Ref[T] = { - asRep[T](mkMethodCall(self, - SigmaDslBuilderClass.getMethod("deserialize", classOf[Sym], classOf[Elem[T]]), - Array[AnyRef](l, cT), - true, false, element[T])) - } } implicit object LiftableSigmaDslBuilder @@ -2107,13 +2100,6 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { Array[AnyRef](l, r), true, true, element[Coll[Byte]])) } - - def deserialize[T](bytes: Ref[Coll[Byte]])(implicit cT: Elem[T]): Ref[T] = { - asRep[T](mkMethodCall(source, - SigmaDslBuilderClass.getMethod("deserialize", classOf[Sym], classOf[Elem[T]]), - Array[AnyRef](bytes, cT), - true, true, element[T])) - } } // entityUnref: single unref method for each type family @@ -2131,9 +2117,7 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { override protected def collectMethods: Map[RMethod, MethodDesc] = { super.collectMethods ++ Elem.declaredMethods(RClass(classOf[SigmaDslBuilder]), RClass(classOf[SSigmaDslBuilder]), Set( - "Colls", "verifyZK", "atLeast", "allOf", "allZK", "anyOf", "anyZK", "xorOf", "sigmaProp", "blake2b256", "sha256", - "byteArrayToBigInt", "longToByteArray", "byteArrayToLong", "proveDlog", "proveDHTuple", "groupGenerator", "substConstants", - "decodePoint", "avlTree", "xor", "deserialize" + "Colls", "verifyZK", "atLeast", "allOf", "allZK", "anyOf", "anyZK", "xorOf", "sigmaProp", "blake2b256", "sha256", "byteArrayToBigInt", "longToByteArray", "byteArrayToLong", "proveDlog", "proveDHTuple", "groupGenerator", "substConstants", "decodePoint", "avlTree", "xor" )) } } @@ -2312,16 +2296,6 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") { def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]])] = unapply(exp.node) } - object deserialize { - def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Elem[T]) forSome {type T}] = d match { - case MethodCall(receiver, method, args, _) if method.getName == "deserialize" && receiver.elem.isInstanceOf[SigmaDslBuilderElem[_]] => - val res = (receiver, args(0), args(1)) - Nullable(res).asInstanceOf[Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Elem[T]) forSome {type T}]] - case _ => Nullable.None - } - def unapply(exp: Sym): Nullable[(Ref[SigmaDslBuilder], Ref[Coll[Byte]], Elem[T]) forSome {type T}] = unapply(exp.node) - } - /** This is necessary to handle CreateAvlTree in GraphBuilding (v6.0) */ object avlTree { def unapply(d: Def[_]): Nullable[(Ref[SigmaDslBuilder], Ref[Byte], Ref[Coll[Byte]], Ref[Int], Ref[WOption[Int]])] = d match { diff --git a/sc/shared/src/test/scala/sigmastate/CompilerTestsBase.scala b/sc/shared/src/test/scala/sigmastate/CompilerTestsBase.scala index a5ae8f1bce..28f907c199 100644 --- a/sc/shared/src/test/scala/sigmastate/CompilerTestsBase.scala +++ b/sc/shared/src/test/scala/sigmastate/CompilerTestsBase.scala @@ -38,7 +38,7 @@ trait CompilerTestsBase extends TestsBase { def checkSerializationRoundTrip(v: SValue): Unit = { val compiledTreeBytes = ValueSerializer.serialize(v) withClue(s"(De)Serialization roundtrip failed for the tree:") { - ValueSerializer.deserialize(compiledTreeBytes) shouldEqual v + ValueSerializer.deserialize(compiledTreeBytes) shouldEqual v } } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 7ef5c080dc..8c75544af3 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -2,17 +2,11 @@ package sigmastate.utxo import org.ergoplatform.ErgoBox.{AdditionalRegisters, R6, R8} import org.ergoplatform._ -import scorex.crypto.authds.{ADKey, ADValue} -import scorex.crypto.authds.avltree.batch.{BatchAVLProver, Insert} -import scorex.crypto.hash.{Blake2b256, Digest32} -import scorex.util.encode.Base16 -import scorex.utils.{Ints, Longs, Shorts} -import sigma.{Colls, SigmaProp} +import sigma.Colls import sigma.Extensions.ArrayOps -import sigma.VersionContext.V6SoftForkVersion import sigma.ast.SCollection.SByteArray import sigma.ast.SType.AnyOps -import sigma.data.{AvlTreeClassTag, AvlTreeData, AvlTreeFlags, CAND, CAnyValue, CSigmaDslBuilder, CSigmaProp, ProveDlog} +import sigma.data.{AvlTreeData, CAnyValue, CSigmaDslBuilder} import sigma.util.StringUtil._ import sigma.ast._ import sigma.ast.syntax._ @@ -26,8 +20,7 @@ import sigmastate.interpreter.Interpreter._ import sigma.ast.Apply import sigma.eval.EvalSettings import sigma.exceptions.InvalidType -import sigma.serialization.{ErgoTreeSerializer, ValueSerializer} -import sigmastate.utils.Helpers +import sigma.serialization.ValueSerializer import sigmastate.utils.Helpers._ import java.math.BigInteger @@ -51,9 +44,7 @@ class BasicOpsSpecification extends CompilerTestingCommons val booleanVar = 9.toByte val propVar1 = 10.toByte val propVar2 = 11.toByte - val propVar3 = 12.toByte - val propBytesVar1 = 13.toByte - val lastExtVar = propBytesVar1 + val lastExtVar = propVar2 val ext: Seq[VarBinding] = Seq( (intVar1, IntConstant(1)), (intVar2, IntConstant(2)), @@ -70,8 +61,7 @@ class BasicOpsSpecification extends CompilerTestingCommons "proofVar2" -> CAnyValue(propVar2) ) - def test(name: String, - env: ScriptEnv, + def test(name: String, env: ScriptEnv, ext: Seq[VarBinding], script: String, propExp: SValue, @@ -82,14 +72,7 @@ class BasicOpsSpecification extends CompilerTestingCommons override lazy val contextExtenders: Map[Byte, EvaluatedValue[_ <: SType]] = { val p1 = dlogSecrets(0).publicImage val p2 = dlogSecrets(1).publicImage - val d1 = dhSecrets(0).publicImage - - (ext ++ Seq( - propVar1 -> SigmaPropConstant(p1), - propVar2 -> SigmaPropConstant(p2), - propVar3 -> SigmaPropConstant(CSigmaProp(CAND(Seq(p1, d1)))), - propBytesVar1 -> ByteArrayConstant(CSigmaProp(CAND(Seq(p1, d1))).propBytes) - )).toMap + (ext ++ Seq(propVar1 -> SigmaPropConstant(p1), propVar2 -> SigmaPropConstant(p2))).toMap } override val evalSettings: EvalSettings = DefaultEvalSettings.copy( isMeasureOperationTime = true, @@ -102,9 +85,8 @@ class BasicOpsSpecification extends CompilerTestingCommons // is not supported by ErgoScript Compiler) // In such cases we use expected property as the property to test propExp.asSigmaProp - } else { + } else compile(env, script).asBoolValue.toSigmaProp - } if (propExp != null) prop shouldBe propExp @@ -177,205 +159,6 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } - property("deserialize - int") { - val bytes = Base16.encode(Ints.toByteArray(5)) - def deserTest() = {test("deserialize", env, ext, - s"{ val ba = fromBase16(\"$bytes\"); Global.deserialize[Int](ba) == 5 }", - null, - true - )} - - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() - } else { - deserTest() - } - } - - property("deserialize - coll") { - - val bytes = Base16.encode(ValueSerializer.serialize(CollectionConstant[SInt.type](Colls.fromArray(Array(IntConstant(5).value)), SInt))) - - def deserTest() = { - test("deserialize", env, ext, - s"{val ba = fromBase16(\"$bytes\"); val coll = Global.deserialize[Coll[Int]](ba); coll(0) == 5 }", - null, - true - ) - } - - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() - } else { - // only primitive types are supported, so the test fails - an [java.lang.reflect.InvocationTargetException] should be thrownBy deserTest() - } - } - - property("deserialize - long roundtrip") { - def deserTest() = test("deserialize", env, ext, - s"""{ - val l = 5L; - val ba = longToByteArray(l); - Global.deserialize[Long](ba) == l - }""", - null, - true - ) - - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() - } else { - deserTest() - } - } - - property("deserialize - box rountrip") { - def deserTest() = test("deserialize", env, ext, - s"""{ - val b = INPUTS(0); - val ba = b.bytes; - Global.deserialize[Box](ba) == b - }""", - null, - true - ) - - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() - } else { - deserTest() - } - } - - property("deserialize - bigint") { - def deserTest() = test("deserialize", env, ext, - s"""{ - val ba = fromBase16("028a5b7f7f7f7f7f7f6c"); - val b = Global.deserialize[BigInt](ba) - b == byteArrayToBigInt(ba) - }""", - null, - true - ) - - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() - } else { - deserTest() - } - } - - property("deserialize - short") { - val s = (-1925).toShort - def deserTest() = test("deserialize", env, ext, - s"""{ - val ba = fromBase16("${Base16.encode(Shorts.toByteArray(s))}"); - Global.deserialize[Short](ba) == -1925 - }""", - null, - true - ) - - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() - } else { - deserTest() - } - } - - property("deserialize - group element") { - val ge = Helpers.decodeGroupElement("026930cb9972e01534918a6f6d6b8e35bc398f57140d13eb3623ea31fbd069939b") - val ba = Base16.encode(ge.getEncoded.toArray) - def deserTest() = test("deserialize", env, Seq(21.toByte -> GroupElementConstant(ge)), - s"""{ - val ge = getVar[GroupElement](21).get - val ba = fromBase16("$ba"); - val ge2 = Global.deserialize[GroupElement](ba) - ba == ge2.getEncoded && ge == ge2 - }""", - null, - true - ) - - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() - } else { - deserTest() - } - } - - property("deserialize - sigmaprop roundtrip") { - - def deserTest() = test("deserialize", env, ext, - s"""{ - val ba = getVar[Coll[Byte]]($propBytesVar1).get - val prop = Global.deserialize[SigmaProp](ba) - prop == getVar[SigmaProp]($propVar3).get && prop - }""", - null, - true - ) - - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() - } else { - deserTest() - } - } - - property("deserialize - sigmaprop roundtrip - non evaluated") { - - val script = GT(Height, IntConstant(-1)).toSigmaProp - val scriptBytes = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(ErgoTree.fromProposition(script)) - val customExt = Seq(21.toByte -> ByteArrayConstant(scriptBytes)) - - def deserTest() = test("deserialize", env, customExt, - s"""{ - val ba = getVar[Coll[Byte]](21).get - val prop = Global.deserialize[SigmaProp](ba) - prop - }""", - null, - true - ) - - if (activatedVersionInTests < V6SoftForkVersion) { - an [sigma.exceptions.TyperException] should be thrownBy deserTest() - } else { - an [Exception] should be thrownBy deserTest() - } - } - - property("deserialize - avltree") { - val elements = Seq(123, 22) - val treeElements = elements.map(i => Longs.toByteArray(i)).map(s => (ADKey @@@ Blake2b256(s), ADValue @@ s)) - val avlProver = new BatchAVLProver[Digest32, Blake2b256.type](keyLength = 32, None) - treeElements.foreach(s => avlProver.performOneOperation(Insert(s._1, s._2))) - avlProver.generateProof() - val treeData = new AvlTreeData(avlProver.digest.toColl, AvlTreeFlags.ReadOnly, 32, None) - val treeBytes = AvlTreeData.serializer.toBytes(treeData) - - val customExt = Seq(21.toByte -> ByteArrayConstant(treeBytes)) - - def deserTest() = test("deserialize", env, customExt, - s"""{ - val ba = getVar[Coll[Byte]](21).get - val tree = Global.deserialize[AvlTree](ba) - tree.digest == fromBase16(${Base16.encode(treeData.digest.toArray)}) && tree.enabledOperations == 0 - }""", - null, - true - ) - - an [Exception] should be thrownBy deserTest() - } - - property("deserialize - header") { - - } - - property("executeFromVar - SigmaProp") { val script = GT(Height, IntConstant(-1)).toSigmaProp val scriptBytes = ValueSerializer.serialize(script) @@ -408,6 +191,7 @@ class BasicOpsSpecification extends CompilerTestingCommons ) } + // test which is showing impossibility of nested Deserialize* property("executeFromVar - deserialize") { val script = DeserializeContext(21.toByte, SSigmaProp) val scriptBytes = ValueSerializer.serialize(script) From 00996ec5997f76479d3105855dd5047654d4bd89 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 27 Nov 2024 22:43:32 +0300 Subject: [PATCH 25/25] scrypto version updated --- build.sbt | 4 ++-- profile-sbt.sh | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) delete mode 100755 profile-sbt.sh diff --git a/build.sbt b/build.sbt index 85c59512d6..ab9d931172 100644 --- a/build.sbt +++ b/build.sbt @@ -82,9 +82,9 @@ ThisBuild / dynverSeparator := "-" val bouncycastleBcprov = "org.bouncycastle" % "bcprov-jdk15on" % "1.66" -val scrypto = "org.scorexfoundation" %% "scrypto" % "2.3.0-4-a0bc6176-SNAPSHOT" +val scrypto = "org.scorexfoundation" %% "scrypto" % "3.0.0" val scryptoDependency = - libraryDependencies += "org.scorexfoundation" %%% "scrypto" % "2.3.0-4-a0bc6176-SNAPSHOT" + libraryDependencies += "org.scorexfoundation" %%% "scrypto" % "3.0.0" val scorexUtil = "org.scorexfoundation" %% "scorex-util" % "0.2.1" val scorexUtilDependency = diff --git a/profile-sbt.sh b/profile-sbt.sh deleted file mode 100755 index b6cd23b569..0000000000 --- a/profile-sbt.sh +++ /dev/null @@ -1,2 +0,0 @@ -sbt -J-agentpath:/Applications/YourKit-Java-Profiler-2018.04.app/Contents/Resources/bin/mac/libyjpagent.jnilib -