From 105bd4e66d72a7e0428d6e0526157b33163a1249 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Mon, 15 Jan 2024 23:47:37 +0300 Subject: [PATCH 01/38] unused mapReduce removed --- .../org/ergoplatform/sdk/Extensions.scala | 23 ------------------- .../org/ergoplatform/sdk/ExtensionsSpec.scala | 6 +---- 2 files changed, 1 insertion(+), 28 deletions(-) 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..84462d81cb 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. 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..32d71abede 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,7 @@ 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.data.{CSigmaDslBuilder, RType} class ExtensionsSpec extends AnyPropSpec with ScalaCheckPropertyChecks with Matchers with CollGens { @@ -13,10 +13,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] => From 8168ea02b03fcd241b8b4b01a8894ee582e6f094 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 16 Jan 2024 00:37:37 +0300 Subject: [PATCH 02/38] DoubleOps removed --- .../src/main/scala/org/ergoplatform/sdk/Extensions.scala | 3 --- 1 file changed, 3 deletions(-) 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 84462d81cb..320aae5919 100644 --- a/sdk/shared/src/main/scala/org/ergoplatform/sdk/Extensions.scala +++ b/sdk/shared/src/main/scala/org/ergoplatform/sdk/Extensions.scala @@ -182,7 +182,4 @@ object Extensions { } } - implicit class DoubleOps(val i: Double) extends AnyVal { - def erg: Long = (i * 1000000000L).toLong - } } From c33801ae3f7e3db0109f3ad7077809e6f838eb5f Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 16 Jan 2024 01:01:55 +0300 Subject: [PATCH 03/38] unused imports in SigmaDslImpl.scala --- .../src/main/scala/special/sigma/impl/SigmaDslImpl.scala | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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..037505b531 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 From bd27625b33f7d6dcf25ae31838e1e76d173bc408 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 16 Jan 2024 01:20:26 +0300 Subject: [PATCH 04/38] removing unused endPass; more unused imports --- .../src/main/scala/sigma/ast/CostItem.scala | 3 --- .../scala/scalan/primitives/Functions.scala | 2 +- .../main/scala/scalan/primitives/Thunks.scala | 2 +- .../scala/scalan/staged/Transforming.scala | 22 ++++++++----------- .../scala/special/collection/CollsUnit.scala | 3 --- 5 files changed, 11 insertions(+), 21 deletions(-) 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/sc/shared/src/main/scala/scalan/primitives/Functions.scala b/sc/shared/src/main/scala/scalan/primitives/Functions.scala index e5cd6f345e..31a6ca8d81 100644 --- a/sc/shared/src/main/scala/scalan/primitives/Functions.scala +++ b/sc/shared/src/main/scala/scalan/primitives/Functions.scala @@ -332,7 +332,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..cd1fac9fd0 100644 --- a/sc/shared/src/main/scala/scalan/staged/Transforming.scala +++ b/sc/shared/src/main/scala/scalan/staged/Transforming.scala @@ -65,10 +65,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 +148,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 +169,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 +186,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 +210,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 +226,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 +243,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/special/collection/CollsUnit.scala b/sc/shared/src/main/scala/special/collection/CollsUnit.scala index 02e62aeb4d..19ae1f5e48 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]; From d378c3b66f82781e7a2214c24f6db5b10873f44b Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 16 Jan 2024 01:31:24 +0300 Subject: [PATCH 05/38] fixing Coll.mapReduce test --- .../src/test/scala/org/ergoplatform/sdk/ExtensionsSpec.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 32d71abede..1f3c8d9064 100644 --- a/sdk/shared/src/test/scala/org/ergoplatform/sdk/ExtensionsSpec.scala +++ b/sdk/shared/src/test/scala/org/ergoplatform/sdk/ExtensionsSpec.scala @@ -5,6 +5,7 @@ import org.scalatest.propspec.AnyPropSpec import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import sigma.{Coll, CollGens} 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 { @@ -24,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 3865cd11eb3a6fb5fa502d8d47ea0f72caf2890a Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 21 Mar 2024 12:26:56 +0300 Subject: [PATCH 06/38] removing more unused arguments --- data/shared/src/main/scala/sigma/ast/SigmaPredef.scala | 2 +- data/shared/src/main/scala/sigma/ast/methods.scala | 7 +++---- data/shared/src/main/scala/sigma/ast/trees.scala | 1 - .../scala/sigma/serialization/ErgoTreeSerializer.scala | 2 +- .../main/scala/sigma/serialization/SigmaSerializer.scala | 4 +--- .../main/scala/sigma/interpreter/js/SigmaPropProver.scala | 1 - .../src/main/scala/org/ergoplatform/ErgoLikeContext.scala | 1 - .../shared/src/main/scala/sigmastate/crypto/GF2_192.scala | 2 -- .../src/main/scala/sigmastate/crypto/GF2_192_Poly.scala | 2 -- .../shared/src/main/scala/sigmastate/eval/CProfiler.scala | 6 +++--- .../main/scala/sigmastate/interpreter/Interpreter.scala | 5 ++--- .../main/scala/sigmastate/interpreter/ProverUtils.scala | 6 ++---- 12 files changed, 13 insertions(+), 26 deletions(-) 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 b637acf792..23a73c9fae 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -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 @@ -720,7 +719,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 }, @@ -766,7 +765,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 _ => @@ -1480,7 +1479,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/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..91765f764b 100644 --- a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala +++ b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala @@ -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/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/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..523b2a7f35 100644 --- a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -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 = { From 059cac1925bf2619a5ed83b875e3254d99125cc7 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 29 Mar 2024 20:21:46 +0300 Subject: [PATCH 07/38] more unused code removed --- data/shared/src/main/scala/sigma/SigmaDataReflection.scala | 3 +-- data/shared/src/main/scala/sigma/ast/SMethod.scala | 2 +- data/shared/src/main/scala/sigma/ast/methods.scala | 2 +- .../src/main/scala/sigmastate/eval/GraphBuilding.scala | 6 ++---- sc/shared/src/main/scala/sigmastate/eval/SigmaLibrary.scala | 2 +- sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala | 6 +++--- sc/shared/src/main/scala/sigmastate/lang/SigmaBinder.scala | 1 - sc/shared/src/test/scala/scalan/LibraryTests.scala | 2 +- 8 files changed, 10 insertions(+), 14 deletions(-) diff --git a/data/shared/src/main/scala/sigma/SigmaDataReflection.scala b/data/shared/src/main/scala/sigma/SigmaDataReflection.scala index 31703b0856..276deaeeee 100644 --- a/data/shared/src/main/scala/sigma/SigmaDataReflection.scala +++ b/data/shared/src/main/scala/sigma/SigmaDataReflection.scala @@ -314,8 +314,7 @@ object SigmaDataReflection { registerClassEntry(clazz, methods = Map( mkMethod(clazz, "xor_eval", Array[Class[_]](classOf[MethodCall], classOf[SigmaDslBuilder], classOf[Coll[_]], classOf[Coll[_]], classOf[ErgoTreeEvaluator])) { (obj, args) => - obj.asInstanceOf[SGlobalMethods.type].xor_eval(args(0).asInstanceOf[MethodCall], - args(1).asInstanceOf[SigmaDslBuilder], + obj.asInstanceOf[SGlobalMethods.type].xor_eval( args(2).asInstanceOf[Coll[Byte]], args(3).asInstanceOf[Coll[Byte]])(args(4).asInstanceOf[ErgoTreeEvaluator]) } 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/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index 23a73c9fae..2cbc2fda8c 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -1494,7 +1494,7 @@ case object SGlobalMethods extends MonoTypeMethods { * Called via reflection based on naming convention. * @see SMethod.evalMethod, Xor.eval, Xor.xorWithCosting */ - def xor_eval(mc: MethodCall, G: SigmaDslBuilder, ls: Coll[Byte], rs: Coll[Byte]) + def xor_eval(ls: Coll[Byte], rs: Coll[Byte]) (implicit E: ErgoTreeEvaluator): Coll[Byte] = { Xor.xorWithCosting(ls, rs) } diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index 9c9fa5ffe1..ed25b6afa4 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala @@ -380,8 +380,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 +434,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 +885,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/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/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 From 08d6b12a73e66d7a1a4903e247154abdb7dfe255 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 2 Apr 2024 22:29:08 +0300 Subject: [PATCH 08/38] unused SSymName.isImportedBy removed --- sc/shared/src/main/scala/scalan/meta/SSymName.scala | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) 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" From de8d3cc849997f5fe60af0d4348a6c4c1742067b Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 2 Apr 2024 22:42:45 +0300 Subject: [PATCH 09/38] unused PassConfig.withConstantPropagation removed --- data/shared/src/main/scala/sigma/ast/methods.scala | 2 +- .../main/scala/sigma/serialization/ErgoTreeSerializer.scala | 4 ++-- .../src/main/scala/sigmastate/interpreter/Interpreter.scala | 2 +- .../sigma/serialization/ConstantSerializerSpecification.scala | 2 +- .../sigma/serialization/DataSerializerSpecification.scala | 1 - sc/shared/src/main/scala/scalan/Library.scala | 2 +- sc/shared/src/main/scala/scalan/staged/Transforming.scala | 3 --- sc/shared/src/main/scala/special/collection/CollsUnit.scala | 2 -- 8 files changed, 6 insertions(+), 12 deletions(-) diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index 2cbc2fda8c..73d9c4b7b8 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -234,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 diff --git a/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala b/data/shared/src/main/scala/sigma/serialization/ErgoTreeSerializer.scala index 91765f764b..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 /** diff --git a/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala b/interpreter/shared/src/main/scala/sigmastate/interpreter/Interpreter.scala index 523b2a7f35..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._ 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/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/staged/Transforming.scala b/sc/shared/src/main/scala/scalan/staged/Transforming.scala index cd1fac9fd0..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 diff --git a/sc/shared/src/main/scala/special/collection/CollsUnit.scala b/sc/shared/src/main/scala/special/collection/CollsUnit.scala index 19ae1f5e48..90f0dca99e 100644 --- a/sc/shared/src/main/scala/special/collection/CollsUnit.scala +++ b/sc/shared/src/main/scala/special/collection/CollsUnit.scala @@ -34,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 From 11c6fe94e3e3938449fcee3a4a111e822fe3ae09 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 2 Apr 2024 22:44:44 +0300 Subject: [PATCH 10/38] CoreByteReader scaladoc cleared --- .../src/main/scala/sigma/serialization/CoreByteReader.scala | 4 ---- 1 file changed, 4 deletions(-) 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 */ From e8978e3c63f5c69d6e719354552cfaa640471a9b Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 3 Apr 2024 00:04:22 +0300 Subject: [PATCH 11/38] unused LambdaOps.{>>,<<} --- sc/shared/src/main/scala/scalan/primitives/Functions.scala | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sc/shared/src/main/scala/scalan/primitives/Functions.scala b/sc/shared/src/main/scala/scalan/primitives/Functions.scala index 31a6ca8d81..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. From 4771208b126d8df6b7b75c31a698cc5dc0efdffc Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 4 Apr 2024 12:24:43 +0100 Subject: [PATCH 12/38] v5.0.14-RC: ScalaDoc for Extensions --- core/shared/src/main/scala/sigma/Extensions.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/shared/src/main/scala/sigma/Extensions.scala b/core/shared/src/main/scala/sigma/Extensions.scala index 865d488803..81976a3c12 100644 --- a/core/shared/src/main/scala/sigma/Extensions.scala +++ b/core/shared/src/main/scala/sigma/Extensions.scala @@ -5,6 +5,9 @@ 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 { @@ -12,6 +15,9 @@ object Extensions { @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) From fcb72297cdae62ab27ee9c5bb4ad3129a304062c Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 4 Apr 2024 12:31:42 +0100 Subject: [PATCH 13/38] v5.0.14-RC: rollback potentially breaking changes --- core/shared/src/main/scala/sigma/Evaluation.scala | 3 +-- core/shared/src/main/scala/sigma/data/package.scala | 1 + core/shared/src/main/scala/sigma/package.scala | 7 +++++-- data/shared/src/main/scala/sigma/ast/syntax.scala | 2 -- .../shared/src/test/scala/sigmastate/lang/LangTests.scala | 1 - .../main/scala/org/ergoplatform/dsl/ContractSyntax.scala | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) 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/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/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/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 _ => From 58997010050f805ec53a9e7ead52e8b9938b9665 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 4 Apr 2024 12:33:03 +0100 Subject: [PATCH 14/38] v5.0.14-RC: Added ScalaDocs for CoreXXX classes --- .../src/main/scala/sigma/data/SigmaPropCodes.scala | 2 +- .../scala/sigma/serialization/CoreByteWriter.scala | 3 +++ .../scala/sigma/serialization/CoreSerializer.scala | 12 +++++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) 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/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. From de8c36299611d5b181149248cd595dd664ed8864 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 4 Apr 2024 12:35:01 +0100 Subject: [PATCH 15/38] v5.0.14-RC: CFunc removed --- .../main/scala/sigmastate/eval/CContext.scala | 56 ------------------- 1 file changed, 56 deletions(-) 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 */ From 6196e90fa66b779ae6a53acaea892cb2412854dd Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 4 Apr 2024 12:50:14 +0100 Subject: [PATCH 16/38] v5.0.14-RC: ScalaDoc for ReflectionData is improved --- .../main/scala/sigma/reflection/ReflectionData.scala | 10 ++++++++-- .../src/main/scala/sigma/SigmaDataReflection.scala | 4 ++++ .../main/scala/sigmastate/InterpreterReflection.scala | 4 ++++ .../src/main/scala/scalan/GraphIRReflection.scala | 4 ++++ 4 files changed, 20 insertions(+), 2 deletions(-) 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/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/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/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. From 2b1e49a6fda8327fdcd7ddbd0a933ea89c20573c Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 4 Apr 2024 19:26:44 +0300 Subject: [PATCH 17/38] RuntimeIRContext removed --- .../scala/sigmastate/eval/IRContext.scala | 8 ++--- .../sigmastate/eval/EvaluationTest.scala | 18 ---------- .../sigmastate/eval/MeasureIRContext.scala | 36 ------------------- 3 files changed, 3 insertions(+), 59 deletions(-) delete mode 100644 sc/shared/src/test/scala/sigmastate/eval/MeasureIRContext.scala diff --git a/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala b/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala index b84098f2e7..a7b6df3f58 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala @@ -10,7 +10,9 @@ import scala.util.Try * 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._ @@ -55,10 +57,6 @@ trait IRContext extends TreeBuilding with GraphBuilding { } } -/** 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 { } 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 - */ -} - From dcec230aea345c8bd10cf23c61d3b5654b4b97e4 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Thu, 4 Apr 2024 19:39:02 +0300 Subject: [PATCH 18/38] xor_eval rollback --- data/shared/src/main/scala/sigma/SigmaDataReflection.scala | 3 ++- data/shared/src/main/scala/sigma/ast/methods.scala | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/data/shared/src/main/scala/sigma/SigmaDataReflection.scala b/data/shared/src/main/scala/sigma/SigmaDataReflection.scala index 9efb3fbf8b..48939b1460 100644 --- a/data/shared/src/main/scala/sigma/SigmaDataReflection.scala +++ b/data/shared/src/main/scala/sigma/SigmaDataReflection.scala @@ -318,7 +318,8 @@ object SigmaDataReflection { registerClassEntry(clazz, methods = Map( mkMethod(clazz, "xor_eval", Array[Class[_]](classOf[MethodCall], classOf[SigmaDslBuilder], classOf[Coll[_]], classOf[Coll[_]], classOf[ErgoTreeEvaluator])) { (obj, args) => - obj.asInstanceOf[SGlobalMethods.type].xor_eval( + obj.asInstanceOf[SGlobalMethods.type].xor_eval(args(0).asInstanceOf[MethodCall], + args(1).asInstanceOf[SigmaDslBuilder], args(2).asInstanceOf[Coll[Byte]], args(3).asInstanceOf[Coll[Byte]])(args(4).asInstanceOf[ErgoTreeEvaluator]) } diff --git a/data/shared/src/main/scala/sigma/ast/methods.scala b/data/shared/src/main/scala/sigma/ast/methods.scala index 73d9c4b7b8..3b7368c542 100644 --- a/data/shared/src/main/scala/sigma/ast/methods.scala +++ b/data/shared/src/main/scala/sigma/ast/methods.scala @@ -1494,7 +1494,7 @@ case object SGlobalMethods extends MonoTypeMethods { * Called via reflection based on naming convention. * @see SMethod.evalMethod, Xor.eval, Xor.xorWithCosting */ - def xor_eval(ls: Coll[Byte], rs: Coll[Byte]) + def xor_eval(mc: MethodCall, G: SigmaDslBuilder, ls: Coll[Byte], rs: Coll[Byte]) (implicit E: ErgoTreeEvaluator): Coll[Byte] = { Xor.xorWithCosting(ls, rs) } From 810ca16eb50b7a33d53e3e20baff9d44ce24f664 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Fri, 5 Apr 2024 12:45:00 +0300 Subject: [PATCH 19/38] IRContext cleared --- .../src/main/scala/sigma/ast/SType.scala | 3 +- .../scala/sigmastate/eval/IRContext.scala | 42 +------------------ .../sigmastate/eval/ErgoScriptTestkit.scala | 27 +++++++++++- .../helpers/CompilerTestingCommons.scala | 3 +- .../utxo/BasicOpsSpecification.scala | 4 +- 5 files changed, 32 insertions(+), 47 deletions(-) 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/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala b/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala index a7b6df3f58..597711d458 100644 --- a/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala +++ b/sc/shared/src/main/scala/sigmastate/eval/IRContext.scala @@ -1,10 +1,6 @@ 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. @@ -15,49 +11,15 @@ import scala.util.Try * @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 script development tools to compile ErgoScript into ErgoTree bytecode. */ -class CompiletimeIRContext extends IRContext { -} - +class CompiletimeIRContext extends IRContext diff --git a/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala b/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala index abbed09992..2832ad27e7 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 => @@ -147,6 +147,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(()) 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)) From bb6224ca8408baf61130d6144e49adfcb10a4da7 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 9 Apr 2024 14:25:48 +0300 Subject: [PATCH 20/38] removing unused code from ContractsTestkit, ErgoScriptTestkit, and MethodCalls --- .../scala/sigmastate/eval/BasicOpsTests.scala | 7 ++-- .../special/sigma/ContractsTestkit.scala | 35 ++----------------- .../src/main/scala/scalan/MethodCalls.scala | 24 ++----------- .../scala/sigma/SigmaDslStaginTests.scala | 4 +-- .../sigmastate/eval/ErgoScriptTestkit.scala | 12 ++----- 5 files changed, 12 insertions(+), 70 deletions(-) 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/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/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/eval/ErgoScriptTestkit.scala b/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala index 2832ad27e7..a10a717d2f 100644 --- a/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala +++ b/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala @@ -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) @@ -208,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() From 815b224e5d506cc267b8672973bd19005e62f9d6 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 10 Apr 2024 19:36:19 +0300 Subject: [PATCH 21/38] 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 22/38] 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 9c93753ccc54359b9b1d870bed42b7eb92103fda Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Mon, 15 Apr 2024 22:39:29 +0300 Subject: [PATCH 23/38] removing unused code from SigmaTestingData --- .../special/sigma/SigmaTestingData.scala | 63 +------------------ 1 file changed, 1 insertion(+), 62 deletions(-) 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)) From a9cf9037c6c5bced20c4d4506a5e5e80dd056a9c Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 17 Apr 2024 18:41:50 +0300 Subject: [PATCH 24/38] SigmaDsl.toBigInteger/BigInt removed --- core/shared/src/main/scala/sigma/SigmaDsl.scala | 6 ------ .../shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala | 4 ---- 2 files changed, 10 deletions(-) diff --git a/core/shared/src/main/scala/sigma/SigmaDsl.scala b/core/shared/src/main/scala/sigma/SigmaDsl.scala index df2b419273..e8ffef3fcf 100644 --- a/core/shared/src/main/scala/sigma/SigmaDsl.scala +++ b/core/shared/src/main/scala/sigma/SigmaDsl.scala @@ -718,12 +718,6 @@ trait SigmaDslBuilder { */ def decodePoint(encoded: Coll[Byte]): GroupElement - /** Create DSL big integer from existing `java.math.BigInteger`*/ - def BigInt(n: BigInteger): BigInt - - /** Extract `java.math.BigInteger` from DSL's `BigInt` type*/ - def toBigInteger(n: BigInt): BigInteger - /** Construct a new authenticated dictionary with given parameters and tree root digest. */ def avlTree(operationFlags: Byte, digest: Coll[Byte], keyLength: Int, valueLengthOpt: Option[Int]): AvlTree diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index 3938feacd3..c806d4a8c5 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -24,10 +24,6 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => override val Colls: CollBuilder = sigma.Colls - override def BigInt(n: BigInteger): BigInt = CBigInt(n) - - override def toBigInteger(n: BigInt): BigInteger = n.asInstanceOf[CBigInt].wrappedValue - /** Wraps the given elliptic curve point into GroupElement type. */ def GroupElement(p: Ecp): GroupElement = p match { case ept: EcPointType => CGroupElement(ept) From 7562e33bce5dfc20c3fc8ba13ebabb3099b82cf3 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Tue, 23 Apr 2024 12:30:55 +0300 Subject: [PATCH 25/38] unused SigmaDslBuilderAdapter.groupGenerator removed --- .../main/scala/special/sigma/impl/SigmaDslImpl.scala | 10 ---------- 1 file changed, 10 deletions(-) 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 037505b531..929d81460d 100644 --- a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -2278,16 +2278,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[_]] => From 2590bfa0e92f9442abb940a69f8d57bd8d3cde1c Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 24 Apr 2024 15:04:49 +0300 Subject: [PATCH 26/38] bigInt predefined function --- .../src/main/scala/sigma/ast/SigmaPredef.scala | 14 ++++++++++++++ docs/LangSpec.md | 6 ++++++ .../scala/sigmastate/lang/SigmaParserTest.scala | 5 +++++ .../scala/sigmastate/lang/SigmaCompilerTest.scala | 9 +++++++++ .../scala/sigmastate/lang/SigmaTyperTest.scala | 1 + 5 files changed, 35 insertions(+) diff --git a/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala b/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala index c4bc32e4a5..8edf9683f5 100644 --- a/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala +++ b/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala @@ -12,6 +12,8 @@ import sigma.exceptions.InvalidArguments import sigma.serialization.CoreByteWriter.ArgInfo import sigma.serialization.ValueSerializer +import java.math.BigInteger + object SigmaPredef { type IrBuilderFunc = PartialFunction[(SValue, Seq[SValue]), SValue] @@ -179,6 +181,17 @@ object SigmaPredef { Seq(ArgInfo("", ""))) ) + val BigIntFromStringFunc = PredefinedFunc("bigInt", + Lambda(Array("input" -> SString), SBigInt, None), + PredefFuncInfo( + { case (_, Seq(arg: EvaluatedValue[SString.type]@unchecked)) => + BigIntConstant(new BigInteger(arg.value)) + }), + OperationInfo(Constant, + """Parsing string argument as a 256-bit signed big integer.""".stripMargin, + Seq(ArgInfo("", ""))) + ) + val FromBase16Func = PredefinedFunc("fromBase16", Lambda(Array("input" -> SString), SByteArray, None), PredefFuncInfo( @@ -402,6 +415,7 @@ object SigmaPredef { SigmaPropFunc, GetVarFunc, DeserializeFunc, + BigIntFromStringFunc, FromBase16Func, FromBase64Func, FromBase58Func, diff --git a/docs/LangSpec.md b/docs/LangSpec.md index ddbb7bd680..59eacc3d80 100644 --- a/docs/LangSpec.md +++ b/docs/LangSpec.md @@ -985,6 +985,12 @@ def proveDHTuple(g: GroupElement, h: GroupElement, */ def proveDlog(value: GroupElement): SigmaProp +/** Transforms Base16 encoded string literal into constant of type Coll[Byte]. + * It is a compile-time operation and only string literal (constant) can be its + * argument. + */ +def bigInt(input: String): BigInt + /** Transforms Base16 encoded string literal into constant of type Coll[Byte]. * It is a compile-time operation and only string literal (constant) can be its * argument. diff --git a/parsers/shared/src/test/scala/sigmastate/lang/SigmaParserTest.scala b/parsers/shared/src/test/scala/sigmastate/lang/SigmaParserTest.scala index 7213088a05..02b28f86ca 100644 --- a/parsers/shared/src/test/scala/sigmastate/lang/SigmaParserTest.scala +++ b/parsers/shared/src/test/scala/sigmastate/lang/SigmaParserTest.scala @@ -615,6 +615,11 @@ class SigmaParserTest extends AnyPropSpec with ScalaCheckPropertyChecks with Mat MethodCallLike(StringConstant("hello"), "+", IndexedSeq(StringConstant("hello"))) } + property("bigInt string decoding") { + parse("""bigInt("32667486267383620946248345338628674027033885928301927616853987602485119134400")""") shouldBe + Apply(BigIntFromStringFunc.symNoType, IndexedSeq(StringConstant("32667486267383620946248345338628674027033885928301927616853987602485119134400"))) + } + property("fromBaseX string decoding") { parse("""fromBase16("1111")""") shouldBe Apply(FromBase16Func.symNoType, IndexedSeq(StringConstant("1111"))) parse("""fromBase58("111")""") shouldBe Apply(FromBase58Func.symNoType, IndexedSeq(StringConstant("111"))) diff --git a/sc/shared/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala b/sc/shared/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala index 88c75a90b6..90e5d21b1e 100644 --- a/sc/shared/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala +++ b/sc/shared/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala @@ -12,6 +12,8 @@ import sigma.ast.{Apply, MethodCall, ZKProofBlock} import sigma.exceptions.{GraphBuildingException, InvalidArguments, TyperException} import sigma.serialization.ValueSerializer import sigma.serialization.generators.ObjectGenerators + +import java.math.BigInteger import scala.annotation.unused class SigmaCompilerTest extends CompilerTestingCommons with LangTests with ObjectGenerators { @@ -127,6 +129,13 @@ class SigmaCompilerTest extends CompilerTestingCommons with LangTests with Objec res shouldEqual SigmaPropConstant(dk1) } + property("bigInt") { + comp(""" bigInt("326674862673836209462483453386286740270338859283019276168539876024851191344") """) shouldBe + BigIntConstant(new BigInteger("326674862673836209462483453386286740270338859283019276168539876024851191344")) + comp(""" bigInt("-10") """) shouldBe + BigIntConstant(-10L) + } + property("fromBaseX") { comp(""" fromBase16("31") """) shouldBe ByteArrayConstant(Array[Byte](49)) comp(""" fromBase58("r") """) shouldBe ByteArrayConstant(Array[Byte](49)) diff --git a/sc/shared/src/test/scala/sigmastate/lang/SigmaTyperTest.scala b/sc/shared/src/test/scala/sigmastate/lang/SigmaTyperTest.scala index 99ad2ae908..a474727943 100644 --- a/sc/shared/src/test/scala/sigmastate/lang/SigmaTyperTest.scala +++ b/sc/shared/src/test/scala/sigmastate/lang/SigmaTyperTest.scala @@ -113,6 +113,7 @@ class SigmaTyperTest extends AnyPropSpec typecheck(env, "min(HEIGHT, INPUTS.size)") shouldBe SInt typecheck(env, "max(1, 2)") shouldBe SInt typecheck(env, "max(1L, 2)") shouldBe SLong + typecheck(env, """bigInt("1111")""") shouldBe SBigInt typecheck(env, """fromBase16("1111")""") shouldBe SByteArray typecheck(env, """fromBase58("111")""") shouldBe SByteArray typecheck(env, """fromBase64("111")""") shouldBe SByteArray From 7ada12a374bd5812db4d81e2e8f3f1483999205d Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Sat, 27 Apr 2024 21:32:30 +0300 Subject: [PATCH 27/38] big int related methods back, TestingInterpreterSpecification.soundness and GraphBuilding.substFromCostTable removed --- core/shared/src/main/scala/sigma/SigmaDsl.scala | 6 ++++++ .../src/main/scala/sigma/data/CSigmaDslBuilder.scala | 4 ++++ .../src/main/scala/sigmastate/eval/GraphBuilding.scala | 4 ---- .../sigmastate/TestingInterpreterSpecification.scala | 8 ++------ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/core/shared/src/main/scala/sigma/SigmaDsl.scala b/core/shared/src/main/scala/sigma/SigmaDsl.scala index e8ffef3fcf..df2b419273 100644 --- a/core/shared/src/main/scala/sigma/SigmaDsl.scala +++ b/core/shared/src/main/scala/sigma/SigmaDsl.scala @@ -718,6 +718,12 @@ trait SigmaDslBuilder { */ def decodePoint(encoded: Coll[Byte]): GroupElement + /** Create DSL big integer from existing `java.math.BigInteger`*/ + def BigInt(n: BigInteger): BigInt + + /** Extract `java.math.BigInteger` from DSL's `BigInt` type*/ + def toBigInteger(n: BigInt): BigInteger + /** Construct a new authenticated dictionary with given parameters and tree root digest. */ def avlTree(operationFlags: Byte, digest: Coll[Byte], keyLength: Int, valueLengthOpt: Option[Int]): AvlTree diff --git a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala index c806d4a8c5..3938feacd3 100644 --- a/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala +++ b/data/shared/src/main/scala/sigma/data/CSigmaDslBuilder.scala @@ -24,6 +24,10 @@ class CSigmaDslBuilder extends SigmaDslBuilder { dsl => override val Colls: CollBuilder = sigma.Colls + override def BigInt(n: BigInteger): BigInt = CBigInt(n) + + override def toBigInteger(n: BigInt): BigInteger = n.asInstanceOf[CBigInt].wrappedValue + /** Wraps the given elliptic curve point into GroupElement type. */ def GroupElement(p: Ecp): GroupElement = p match { case ept: EcPointType => CGroupElement(ept) diff --git a/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala b/sc/shared/src/main/scala/sigmastate/eval/GraphBuilding.scala index ed25b6afa4..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 diff --git a/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index fe5a678679..66c7099436 100644 --- a/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -24,13 +24,9 @@ class TestingInterpreterSpecification extends CompilerTestingCommons with CompilerCrossVersionProps with BeforeAndAfterAll { implicit lazy val IR: TestingIRContext = new TestingIRContext - lazy val prover = new ErgoLikeTestProvingInterpreter() { - } - - 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, From e0795c54565be916a9bbe84c4200abb699d547df Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Sat, 27 Apr 2024 22:01:06 +0300 Subject: [PATCH 28/38] implicits removed #1 --- .../src/main/scala/special/sigma/impl/SigmaDslImpl.scala | 2 -- sc/shared/src/test/scala/sigma/SigmaDslTesting.scala | 4 ++-- .../test/scala/sigmastate/SoftForkabilitySpecification.scala | 4 ++-- .../scala/sigmastate/TestingInterpreterSpecification.scala | 5 +++-- 4 files changed, 7 insertions(+), 8 deletions(-) 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 929d81460d..70fb35c329 100644 --- a/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala +++ b/sc/shared/src/main/scala/special/sigma/impl/SigmaDslImpl.scala @@ -1915,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), @@ -2075,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), diff --git a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala index 46222d9fb1..cd99f5498c 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala @@ -1152,8 +1152,8 @@ class SigmaDslTesting extends AnyPropSpec (cases: Seq[A], f: Feature[A, B], nIters: Int, formatter: MeasureFormatter[A]) (implicit IR: IRContext, evalSettings: EvalSettings): Seq[Long] = { val fNew = f.newF - implicit val tA = fNew.tA - implicit val tB = fNew.tB + val tA = fNew.tA + val tB = fNew.tB implicit val cs = defaultCompilerSettings val func = funcJit[A, B](f.script) val noTraceSettings = evalSettings.copy( 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 66c7099436..446f1972a7 100644 --- a/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -22,7 +22,8 @@ import scala.util.Random class TestingInterpreterSpecification extends CompilerTestingCommons with CompilerCrossVersionProps with BeforeAndAfterAll { - implicit lazy val IR: TestingIRContext = new TestingIRContext + + val IR: TestingIRContext = new TestingIRContext lazy val prover = new ErgoLikeTestProvingInterpreter() @@ -124,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) From 7f01f11403b9807558f80e25cfb704cf2a9a1280 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Sun, 28 Apr 2024 02:01:10 +0300 Subject: [PATCH 29/38] rolling back implicits in benchmarkCases --- sc/shared/src/test/scala/sigma/SigmaDslTesting.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala index cd99f5498c..46222d9fb1 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala @@ -1152,8 +1152,8 @@ class SigmaDslTesting extends AnyPropSpec (cases: Seq[A], f: Feature[A, B], nIters: Int, formatter: MeasureFormatter[A]) (implicit IR: IRContext, evalSettings: EvalSettings): Seq[Long] = { val fNew = f.newF - val tA = fNew.tA - val tB = fNew.tB + implicit val tA = fNew.tA + implicit val tB = fNew.tB implicit val cs = defaultCompilerSettings val func = funcJit[A, B](f.script) val noTraceSettings = evalSettings.copy( From 691c5eecccd3ae5a9a519b7e1b9fb143ef3e7ac8 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Sun, 28 Apr 2024 02:13:13 +0300 Subject: [PATCH 30/38] CoreArrayByteOps removed --- core/js/src/main/scala/sigma/js/GroupElement.scala | 4 ++-- core/shared/src/main/scala/sigma/Environment.scala | 2 +- core/shared/src/main/scala/sigma/Extensions.scala | 5 ----- 3 files changed, 3 insertions(+), 8 deletions(-) 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/Extensions.scala b/core/shared/src/main/scala/sigma/Extensions.scala index 81976a3c12..0c79df94ea 100644 --- a/core/shared/src/main/scala/sigma/Extensions.scala +++ b/core/shared/src/main/scala/sigma/Extensions.scala @@ -9,11 +9,6 @@ import sigma.data.RType * 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. From 72814c0786c5c01b3d6904956d9da5129dfca4c7 Mon Sep 17 00:00:00 2001 From: Alexander Chepurnoy Date: Wed, 1 May 2024 13:43:29 +0300 Subject: [PATCH 31/38] 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 45325928254349f21e3ab9bae784b101ce9fd950 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 1 May 2024 12:26:42 +0100 Subject: [PATCH 32/38] es-bigint: fixes in ScalaDocs --- data/shared/src/main/scala/sigma/ast/SigmaPredef.scala | 2 +- docs/LangSpec.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala b/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala index 8edf9683f5..631f7f2d75 100644 --- a/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala +++ b/data/shared/src/main/scala/sigma/ast/SigmaPredef.scala @@ -188,7 +188,7 @@ object SigmaPredef { BigIntConstant(new BigInteger(arg.value)) }), OperationInfo(Constant, - """Parsing string argument as a 256-bit signed big integer.""".stripMargin, + """Parsing string literal argument as a 256-bit signed big integer.""".stripMargin, Seq(ArgInfo("", ""))) ) diff --git a/docs/LangSpec.md b/docs/LangSpec.md index 59eacc3d80..ba66748f08 100644 --- a/docs/LangSpec.md +++ b/docs/LangSpec.md @@ -985,7 +985,7 @@ def proveDHTuple(g: GroupElement, h: GroupElement, */ def proveDlog(value: GroupElement): SigmaProp -/** Transforms Base16 encoded string literal into constant of type Coll[Byte]. +/** Transforms Base16 encoded string literal into constant of type BigInt. * It is a compile-time operation and only string literal (constant) can be its * argument. */ From 60660f20656370e0c191266604211c4866c34db7 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 2 May 2024 13:43:28 +0100 Subject: [PATCH 33/38] i956-box-in-register: moved Value to sigma-data --- .../src/main/scala/sigma/data/js/Isos.scala | 152 ++++++++++ data/js/src/main/scala/sigma/js/Box.scala | 61 ++++ data/js/src/main/scala/sigma/js/Value.scala | 266 ++++++++++++++++++ .../scala/org/ergoplatform/sdk/js/Isos.scala | 204 ++------------ .../ergoplatform/sdk/js/ProverBuilder.scala | 9 +- .../org/ergoplatform/sdk/js/SigmaProver.scala | 4 +- .../org/ergoplatform/sdk/js/IsosSpec.scala | 22 +- 7 files changed, 521 insertions(+), 197 deletions(-) create mode 100644 data/js/src/main/scala/sigma/data/js/Isos.scala create mode 100644 data/js/src/main/scala/sigma/js/Box.scala create mode 100644 data/js/src/main/scala/sigma/js/Value.scala diff --git a/data/js/src/main/scala/sigma/data/js/Isos.scala b/data/js/src/main/scala/sigma/data/js/Isos.scala new file mode 100644 index 0000000000..95bbce8bbe --- /dev/null +++ b/data/js/src/main/scala/sigma/data/js/Isos.scala @@ -0,0 +1,152 @@ +package sigma.data.js + +import org.ergoplatform.{ErgoBox, ErgoBoxCandidate} +import org.ergoplatform.ErgoBox._ +import scorex.crypto.authds.ADKey +import scorex.util.ModifierId +import scorex.util.encode.Base16 +import sigma.{Coll, Colls} +import sigmastate.fleetSdkCommon.distEsmTypesBoxesMod.{Box => FBox} +import sigmastate.fleetSdkCommon.distEsmTypesCommonMod.{Amount, HexString} +import sigmastate.fleetSdkCommon.distEsmTypesRegistersMod.NonMandatoryRegisters +import sigmastate.fleetSdkCommon.{distEsmTypesBoxesMod => boxesMod, distEsmTypesCommonMod => commonMod, distEsmTypesRegistersMod => registersMod, distEsmTypesTokenMod => tokenMod} +import sigma.Extensions._ +import sigma.ast.syntax.GroupElementConstant +import sigma.ast.{Constant, GroupElementConstant, SType} +import sigma.data.Iso.isoStringToArray +import sigma.data.{CGroupElement, Digest32Coll, Iso} +import sigma.js.GroupElement +import sigma.serialization.{ErgoTreeSerializer, ValueSerializer} + +import scala.scalajs.js + +/** Definitions of isomorphisms for sigma-data module. */ +object Isos { + + val isoStringToGroupElement: Iso[String, sigma.GroupElement] = new Iso[String, sigma.GroupElement] { + override def to(x: String): sigma.GroupElement = { + val bytes = Base16.decode(x).get + ValueSerializer.deserialize(bytes).asInstanceOf[GroupElementConstant].value + } + override def from(x: sigma.GroupElement): String = { + val bytes = ValueSerializer.serialize(GroupElementConstant(x)) + Base16.encode(bytes) + } + } + + val isoGroupElement: Iso[GroupElement, sigma.GroupElement] = new Iso[GroupElement, sigma.GroupElement] { + override def to(x: GroupElement): sigma.GroupElement = { + CGroupElement(x.point) + } + override def from(x: sigma.GroupElement): GroupElement = { + new GroupElement(x.asInstanceOf[CGroupElement].wrappedValue) + } + } + + implicit val isoBoxId: Iso[boxesMod.BoxId, ErgoBox.BoxId] = new Iso[boxesMod.BoxId, ErgoBox.BoxId] { + override def to(x: boxesMod.BoxId): ErgoBox.BoxId = ADKey @@@ isoStringToArray.to(x) + + override def from(x: ErgoBox.BoxId): boxesMod.BoxId = isoStringToArray.from(x) + } + + implicit val isoHexStringToConstant: Iso[HexString, Constant[SType]] = new Iso[HexString, Constant[SType]] { + override def to(x: HexString): Constant[SType] = { + val bytes = isoStringToArray.to(x) + val value = ValueSerializer.deserialize(bytes) + value.asInstanceOf[Constant[SType]] + } + override def from(x: Constant[SType]): HexString = { + val bytes = ValueSerializer.serialize(x) + isoStringToArray.from(bytes) + } + } + + + implicit val isoAmount: Iso[commonMod.Amount, Long] = new Iso[commonMod.Amount, Long] { + override def to(x: commonMod.Amount): Long = x.asInstanceOf[Any] match { + case s: String => BigInt(s).toLong + case _ => java.lang.Long.parseLong(x.asInstanceOf[js.BigInt].toString(10)) + } + override def from(x: Long): commonMod.Amount = x.toString + } + + implicit val isoToken: Iso[tokenMod.TokenAmount[commonMod.Amount], Token] = + new Iso[tokenMod.TokenAmount[commonMod.Amount], Token] { + override def to(x: tokenMod.TokenAmount[commonMod.Amount]): Token = + (Digest32Coll @@@ Colls.fromArray(Base16.decode(x.tokenId).get), isoAmount.to(x.amount)) + + override def from(x: Token): tokenMod.TokenAmount[commonMod.Amount] = + tokenMod.TokenAmount[commonMod.Amount](isoAmount.from(x._2), x._1.toHex) + } + + val isoTokenArray: Iso[js.Array[tokenMod.TokenAmount[commonMod.Amount]], Coll[Token]] = + new Iso[js.Array[tokenMod.TokenAmount[commonMod.Amount]], Coll[Token]] { + override def to(x: js.Array[tokenMod.TokenAmount[commonMod.Amount]]): Coll[Token] = { + sigma.js.Isos.isoArrayToColl(isoToken).to(x) + } + override def from(x: Coll[Token]): js.Array[tokenMod.TokenAmount[commonMod.Amount]] = { + sigma.js.Isos.isoArrayToColl(isoToken).from(x) + } + } + + val isoNonMandatoryRegisters: Iso[registersMod.NonMandatoryRegisters, AdditionalRegisters] = + new Iso[registersMod.NonMandatoryRegisters, AdditionalRegisters] { + override def to(x: registersMod.NonMandatoryRegisters): AdditionalRegisters = { + val regs = Seq( + x.R4 -> R4, + x.R5 -> R5, + x.R6 -> R6, + x.R7 -> R7, + x.R8 -> R8, + x.R9 -> R9 + ).collect { + case (regOpt, id) if regOpt.isDefined => id -> isoHexStringToConstant.to(regOpt.get) + } + Map(regs:_*) + } + override def from(regs: AdditionalRegisters): registersMod.NonMandatoryRegisters = { + def regHexOpt(t: NonMandatoryRegisterId): Option[HexString] = + regs.get(t).map(v => isoHexStringToConstant.from(v.asInstanceOf[Constant[SType]])) + + val resRegs = NonMandatoryRegisters() + regHexOpt(R4).foreach(resRegs.setR4(_)) + regHexOpt(R5).foreach(resRegs.setR5(_)) + regHexOpt(R6).foreach(resRegs.setR6(_)) + regHexOpt(R7).foreach(resRegs.setR7(_)) + regHexOpt(R8).foreach(resRegs.setR8(_)) + regHexOpt(R9).foreach(resRegs.setR9(_)) + resRegs + } + } + + implicit val isoBoxCandidate: Iso[boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters], ErgoBoxCandidate] = new Iso[boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters], ErgoBoxCandidate] { + override def to(x: boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters]): ErgoBoxCandidate = { + val ergoBoxCandidate = new ErgoBoxCandidate( + value = isoAmount.to(x.value), + ergoTree = { + val bytes = Base16.decode(x.ergoTree).get + ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes) + }, + x.creationHeight.toInt, + additionalTokens = isoTokenArray.to(x.assets), + additionalRegisters = isoNonMandatoryRegisters.to(x.additionalRegisters) + ) + ergoBoxCandidate + } + + override def from(x: ErgoBoxCandidate): boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters] = { + val ergoTree = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(x.ergoTree) + val ergoTreeStr = Base16.encode(ergoTree) + val assets = isoTokenArray.from(x.additionalTokens) + boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters]( + ergoTree = ergoTreeStr, + value = isoAmount.from(x.value), + assets = assets, + creationHeight = x.creationHeight, + additionalRegisters = isoNonMandatoryRegisters.from(x.additionalRegisters) + ) + } + } + + +} diff --git a/data/js/src/main/scala/sigma/js/Box.scala b/data/js/src/main/scala/sigma/js/Box.scala new file mode 100644 index 0000000000..209e15d489 --- /dev/null +++ b/data/js/src/main/scala/sigma/js/Box.scala @@ -0,0 +1,61 @@ +package sigma.js + +import org.ergoplatform.ErgoBox +import scorex.util.ModifierId +import scorex.util.encode.Base16 +import sigma.data.Iso +import sigma.data.js.Isos.{isoAmount, isoNonMandatoryRegisters, isoTokenArray} +import sigma.serialization.ErgoTreeSerializer +import sigmastate.fleetSdkCommon.distEsmTypesBoxesMod.{Box => FBox} +import sigmastate.fleetSdkCommon.distEsmTypesCommonMod.Amount +import sigmastate.fleetSdkCommon.distEsmTypesRegistersMod.NonMandatoryRegisters +import sigmastate.fleetSdkCommon.{distEsmTypesCommonMod => commonMod} + +import scala.scalajs.js +import scala.scalajs.js.annotation.JSExportTopLevel + +/** Equivalent of [[sigma.Box]] available from JS. */ +@JSExportTopLevel("Box") +class Box(val box: FBox[Amount, NonMandatoryRegisters]) extends js.Object { +} + +@JSExportTopLevel("Box$") +object Box extends js.Object { + + /** Converts Fleet box to ErgoBox and back. */ + val isoBox: Iso[FBox[commonMod.Amount, NonMandatoryRegisters], ErgoBox] = new Iso[FBox[commonMod.Amount, NonMandatoryRegisters], ErgoBox] { + override def to(x: FBox[commonMod.Amount, NonMandatoryRegisters]): ErgoBox = { + val ergoBox = new ErgoBox( + value = isoAmount.to(x.value), + ergoTree = { + val bytes = Base16.decode(x.ergoTree).get + ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes) + }, + creationHeight = x.creationHeight.toInt, + additionalTokens = isoTokenArray.to(x.assets), + additionalRegisters = isoNonMandatoryRegisters.to(x.additionalRegisters), + transactionId = ModifierId @@ x.transactionId, + index = x.index.toShort + ) + ergoBox + } + + override def from(x: ErgoBox): FBox[commonMod.Amount, NonMandatoryRegisters] = { + val ergoTree = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(x.ergoTree) + val ergoTreeStr = Base16.encode(ergoTree) + val assets = isoTokenArray.from(x.additionalTokens) + FBox[commonMod.Amount, NonMandatoryRegisters]( + boxId = Base16.encode(x.id), + ergoTree = ergoTreeStr, + value = isoAmount.from(x.value), + assets = assets, + creationHeight = x.creationHeight, + additionalRegisters = isoNonMandatoryRegisters.from(x.additionalRegisters), + transactionId = x.transactionId, + index = x.index + ) + } + } + + +} \ No newline at end of file diff --git a/data/js/src/main/scala/sigma/js/Value.scala b/data/js/src/main/scala/sigma/js/Value.scala new file mode 100644 index 0000000000..785f9e04db --- /dev/null +++ b/data/js/src/main/scala/sigma/js/Value.scala @@ -0,0 +1,266 @@ +package sigma +package js + +import scorex.util.Extensions.{IntOps, LongOps} +import scorex.util.encode.Base16 +import sigma.ast.SType +import sigma.crypto.Platform +import sigma.data._ +import sigma.js.Value.toRuntimeData +import sigma.serialization.{CoreSerializer, DataSerializer} +import sigma.util.Extensions.BigIntOps +import sigma.{Coll, Colls, Evaluation} + +import java.math.BigInteger +import scala.scalajs.js +import scala.scalajs.js.annotation.JSExportTopLevel + +/** + * This class is used to represent any valid value of ErgoScript language. + * Any such value comes equipped with {@link Type} descriptor. + * Note, there is a distinction between JS types and ErgoScript types. + * Each Value instance represents the concrete ErgoScript type given by `tpe`. + * The implementation is based on the pre-defined mapping between JS and ES types. + * This mapping is applied recursively and is given by the following: + * + * JS type | ErgoScript Type + * -------------------------------------- + * Number | Byte + * Number | Short + * Number | Int + * BigInt | Long + * BigInt | BigInt + * array [A, B] | (A, B) - pair + * array [a1, a2 ..] | Coll[A] - collection + * + * @param data JS value wrapped in this value + * @param tpe type descriptor of the ErgoScript type + */ +@JSExportTopLevel("Value") +class Value(val data: Any, val tpe: Type) extends js.Object { + + /** Get Sigma runtime value which can be passed to interpreter, saved in register and + * [[sigma.ast.Constant]] nodes. + */ + final def runtimeData: Any = toRuntimeData(data, tpe.rtype) + + /** + * Encode this value as Base16 hex string. + * 1) it transforms this value into {@link sigma.ast.ConstantNode} of sigma. + * 2) it serializes the constant into byte array using {@link sigmastate.serialization.ConstantSerializer} + * 3) the bytes are encoded using Base16 encoder into string + * + * @return hex string of serialized bytes + */ + def toHex(): String = { + val stype = Evaluation.rtypeToSType(tpe.rtype) + val value = runtimeData.asInstanceOf[SType#WrappedType] + val w = CoreSerializer.startWriter() + w.putType(stype) + DataSerializer.serialize(value, stype, w) + Base16.encode(w.toBytes) + } +} + +@JSExportTopLevel("Value$") +object Value extends js.Object { + /** Maximal positive value of ES type Long */ + val MaxLong = js.BigInt("0x7fffffffffffffff") + + /** Minimal negative value of ES type Long */ + val MinLong = -js.BigInt("0x8000000000000000") + + /** Helper method to get Sigma runtime value which can be passed to interpreter, saved + * in register and [[sigma.ast.Constant]] nodes. + */ + final private[js] def toRuntimeData(data: Any, rtype: RType[_]): Any = rtype match { + case sigma.BooleanType => data + case sigma.ByteType | sigma.ShortType | sigma.IntType => data + case sigma.LongType => java.lang.Long.parseLong(data.asInstanceOf[js.BigInt].toString(10)) + case sigma.BigIntRType => + val v = data.asInstanceOf[js.BigInt] + CBigInt(new BigInteger(v.toString(16), 16)) + case sigma.GroupElementRType => + val ge = data.asInstanceOf[GroupElement] + CGroupElement(ge.point) + case sigma.SigmaPropRType => + val p = data.asInstanceOf[SigmaProp] + CSigmaProp(p.sigmaBoolean) + case sigma.AvlTreeRType => + val t = data.asInstanceOf[AvlTree] + AvlTree.isoAvlTree.to(t) + case sigma.BoxRType => + val t = data.asInstanceOf[Box] + CBox(Box.isoBox.to(t.box)) + case ct: CollType[a] => + val xs = data.asInstanceOf[js.Array[Any]] + implicit val cT = ct.tItem.classTag + val items = xs.map(x => toRuntimeData(x, ct.tItem).asInstanceOf[a]).toArray[a] + Colls.fromItems(items:_*)(ct.tItem) + case pt: PairType[a, b] => + val p = data.asInstanceOf[js.Array[Any]] + val x = toRuntimeData(p(0), pt.tFst).asInstanceOf[a] + val y = toRuntimeData(p(1), pt.tSnd).asInstanceOf[b] + (x, y) + case sigma.UnitType => data + case _ => + throw new IllegalArgumentException(s"Unsupported type $rtype") + } + + /** Helper method to extract JS data value from Sigma runtime value. + * This should be inverse to `toRuntimeData`. + * + * @param value runtime value of type given by `rtype` + * @param rtype type descriptor of Sigma runtime value + */ + final def fromRuntimeData(value: Any, rtype: RType[_]): Any = rtype match { + case sigma.BooleanType => value + case sigma.ByteType | sigma.ShortType | sigma.IntType => value + case sigma.LongType => js.BigInt(value.asInstanceOf[Long].toString) + case sigma.BigIntRType => + val hex = value.asInstanceOf[sigma.BigInt].toBigInteger.toString(10) + js.BigInt(hex) + case sigma.GroupElementRType => + val point = value.asInstanceOf[CGroupElement].wrappedValue.asInstanceOf[Platform.Ecp] + new GroupElement(point) + case sigma.SigmaPropRType => + new SigmaProp(value.asInstanceOf[CSigmaProp].wrappedValue) + case sigma.AvlTreeRType => + AvlTree.isoAvlTree.from(value.asInstanceOf[CAvlTree]) + case sigma.BoxRType => + AvlTree.isoAvlTree.from(value.asInstanceOf[CAvlTree]) + case ct: CollType[a] => + val arr = value.asInstanceOf[Coll[a]].toArray + js.Array(arr.map(x => fromRuntimeData(x, ct.tItem)):_*) + case pt: PairType[a, b] => + val p = value.asInstanceOf[(a, b)] + js.Array(fromRuntimeData(p._1, pt.tFst), fromRuntimeData(p._2, pt.tSnd)) + case sigma.UnitType => value + case _ => + throw new IllegalArgumentException(s"Unsupported type $rtype") + } + + /** Helper method to check validity of JS data value against the given runtime type. + * + * @param data js value + * @param rtype type descriptor of Sigma runtime value + */ + final private def checkJsData[T](data: T, rtype: RType[_]): Any = rtype match { + case sigma.ByteType => data.asInstanceOf[Int].toByteExact + case sigma.ShortType => data.asInstanceOf[Int].toShortExact + case sigma.IntType => data.asInstanceOf[Int].toLong.toIntExact + case sigma.LongType => + val n = data.asInstanceOf[js.BigInt] + if (n < MinLong || n > MaxLong) + throw new ArithmeticException(s"value $n is out of long range") + n + case sigma.BigIntRType => + data.asInstanceOf[js.BigInt] + case sigma.GroupElementRType => + data.asInstanceOf[GroupElement] + case sigma.SigmaPropRType => + data.asInstanceOf[SigmaProp] + case PairType(l, r) => data match { + case arr: js.Array[Any @unchecked] => + checkJsData(arr(0), l) + checkJsData(arr(1), r) + data + case _ => + throw new ArithmeticException(s"$data cannot represent pair value") + } + case CollType(elemType) => data match { + case arr: js.Array[Any @unchecked] => + arr.foreach(x => checkJsData(x, elemType)) + data + case _ => + throw new ArithmeticException(s"$data cannot represent Coll value") + } + case _ => + throw new IllegalArgumentException(s"Unsupported type $rtype") + } + + /** Create Byte value from JS number. */ + def ofByte(n: Int): Value = { + checkJsData(n, Type.Byte.rtype) + new Value(n, Type.Byte) + } + + /** Create Short value from JS number. */ + def ofShort(n: Int): Value = { + checkJsData(n, Type.Short.rtype) + new Value(n, Type.Short) + } + + /** Create Int value from JS number. */ + def ofInt(n: Int): Value = { + checkJsData(n, Type.Int.rtype) + new Value(n, Type.Int) + } + + /** Create Long value from JS BigInt. */ + def ofLong(n: js.BigInt): Value = { + checkJsData(n, Type.Long.rtype) + new Value(n, Type.Long) + } + + /** Create BigInt value from JS BigInt. */ + def ofBigInt(n: js.BigInt): Value = { + checkJsData(n, Type.BigInt.rtype) + new Value(n, Type.BigInt) + } + + /** Creates a Value of GroupElement type from [[sigmastate.crypto.Platform.Point]] hex. + * @param pointHex hex of ASN representation of [[sigmastate.crypto.Platform.Point]] + */ + def ofGroupElement(pointHex: String): Value = { + val ge = GroupElement.fromPointHex(pointHex) + new Value(ge, Type.GroupElement) + } + + /** Creates a Value of SigmaProp type from [[sigmastate.crypto.Platform.Point]] hex. + * @param pointHex hex of ASN representation of [[sigmastate.crypto.Platform.Point]] + */ + def ofSigmaProp(pointHex: String): Value = { + val sp = SigmaProp.fromPointHex(pointHex) + new Value(sp, Type.SigmaProp) + } + + /** Create Pair value from two values. */ + def pairOf(l: Value, r: Value): Value = { + val data = js.Array(l.data, r.data) // the l and r data have been validated + new Value(data, Type.pairType(l.tpe, r.tpe)) + } + + /** Create Coll value from array and element type descriptor. + * @param items collection elements which should be valid JS representation of `elemType` + * @param elemType descriptor of types for collection elements + */ + def collOf(items: js.Array[Any], elemType: Type): Value = { + val t = Type.collType(elemType) + checkJsData(items, t.rtype) + new Value(items, t) + } + + /** + * Creates Value from hex encoded serialized bytes of Constant values. + *

+ * In order to create Value you need to provide both value instance and + * Type descriptor. This is similar to how values are represented in sigma + * ConstantNode. Each ConstantNode also have value instance and `tpe: SType` + * descriptor. + * @param hex the string is obtained as hex encoding of serialized ConstantNode. + * (The bytes obtained by ConstantSerializer in sigma) + * @return new deserialized Value instance containing: + * - suitable JS value in its `data` field + * - and [[Type]] descriptor in its `tpe` field + */ + def fromHex(hex: String): Value = { + val bytes = Base16.decode(hex).fold(t => throw t, identity) + val r = CoreSerializer.startReader(bytes) + val stype = r.getType() + val value = DataSerializer.deserialize(stype, r) + val rtype = Evaluation.stypeToRType(stype) + val jsvalue = Value.fromRuntimeData(value, rtype) + new Value(jsvalue, new Type(rtype)) + } +} diff --git a/sdk/js/src/main/scala/org/ergoplatform/sdk/js/Isos.scala b/sdk/js/src/main/scala/org/ergoplatform/sdk/js/Isos.scala index f6393f62bb..f4085cf2a9 100644 --- a/sdk/js/src/main/scala/org/ergoplatform/sdk/js/Isos.scala +++ b/sdk/js/src/main/scala/org/ergoplatform/sdk/js/Isos.scala @@ -24,52 +24,14 @@ import sigmastate.fleetSdkCommon.distEsmTypesRegistersMod.NonMandatoryRegisters import sigmastate.fleetSdkCommon.distEsmTypesTokenMod.TokenAmount import sigmastate.fleetSdkCommon.distEsmTypesTransactionsMod.{SignedTransaction, UnsignedTransaction} import sigmastate.fleetSdkCommon.{distEsmTypesBoxesMod => boxesMod, distEsmTypesCommonMod => commonMod, distEsmTypesContextExtensionMod => contextExtensionMod, distEsmTypesInputsMod => inputsMod, distEsmTypesProverResultMod => proverResultMod, distEsmTypesRegistersMod => registersMod, distEsmTypesTokenMod => tokenMod} - +import sigma.data.js.{Isos => DataIsos} import java.math.BigInteger import scala.collection.immutable.ListMap import scala.scalajs.js import scala.scalajs.js.Object -/** Definitions of isomorphisms. */ +/** Definitions of isomorphisms for sigma-sdk module. */ object Isos { - val isoStringToGroupElement: Iso[String, sigma.GroupElement] = new Iso[String, sigma.GroupElement] { - override def to(x: String): sigma.GroupElement = { - val bytes = Base16.decode(x).get - ValueSerializer.deserialize(bytes).asInstanceOf[GroupElementConstant].value - } - override def from(x: sigma.GroupElement): String = { - val bytes = ValueSerializer.serialize(GroupElementConstant(x)) - Base16.encode(bytes) - } - } - - val isoGroupElement: Iso[GroupElement, sigma.GroupElement] = new Iso[GroupElement, sigma.GroupElement] { - override def to(x: GroupElement): sigma.GroupElement = { - CGroupElement(x.point) - } - override def from(x: sigma.GroupElement): GroupElement = { - new GroupElement(x.asInstanceOf[CGroupElement].wrappedValue) - } - } - - implicit val isoBoxId: Iso[boxesMod.BoxId, ErgoBox.BoxId] = new Iso[boxesMod.BoxId, ErgoBox.BoxId] { - override def to(x: boxesMod.BoxId): ErgoBox.BoxId = ADKey @@@ isoStringToArray.to(x) - - override def from(x: ErgoBox.BoxId): boxesMod.BoxId = isoStringToArray.from(x) - } - - implicit val isoHexStringToConstant: Iso[HexString, Constant[SType]] = new Iso[HexString, Constant[SType]] { - override def to(x: HexString): Constant[SType] = { - val bytes = isoStringToArray.to(x) - val value = ValueSerializer.deserialize(bytes) - value.asInstanceOf[Constant[SType]] - } - override def from(x: Constant[SType]): HexString = { - val bytes = ValueSerializer.serialize(x) - isoStringToArray.from(bytes) - } - } - implicit val isoHeader: Iso[Header, sigma.Header] = new Iso[Header, sigma.Header] { override def to(a: Header): sigma.Header = { CHeader( @@ -83,8 +45,8 @@ object Isos { nBits = sigma.js.Isos.isoBigIntToLong.to(a.nBits), height = a.height, extensionRoot = isoStringToColl.to(a.extensionRoot), - minerPk = isoGroupElement.to(a.minerPk), - powOnetimePk = isoGroupElement.to(a.powOnetimePk), + minerPk = DataIsos.isoGroupElement.to(a.minerPk), + powOnetimePk = DataIsos.isoGroupElement.to(a.powOnetimePk), powNonce = isoStringToColl.to(a.powNonce), powDistance = sigma.js.Isos.isoBigInt.to(a.powDistance), votes = isoStringToColl.to(a.votes) @@ -103,8 +65,8 @@ object Isos { nBits = sigma.js.Isos.isoBigIntToLong.from(header.nBits), height = header.height, extensionRoot = isoStringToColl.from(header.extensionRoot), - minerPk = isoGroupElement.from(header.minerPk), - powOnetimePk = isoGroupElement.from(header.powOnetimePk), + minerPk = DataIsos.isoGroupElement.from(header.minerPk), + powOnetimePk = DataIsos.isoGroupElement.from(header.powOnetimePk), powNonce = isoStringToColl.from(header.powNonce), powDistance = sigma.js.Isos.isoBigInt.from(header.powDistance), votes = isoStringToColl.from(header.votes) @@ -120,7 +82,7 @@ object Isos { timestamp = sigma.js.Isos.isoBigIntToLong.to(a.timestamp), nBits = sigma.js.Isos.isoBigIntToLong.to(a.nBits), height = a.height, - minerPk = isoGroupElement.to(a.minerPk), + minerPk = DataIsos.isoGroupElement.to(a.minerPk), votes = isoStringToColl.to(a.votes) ) } @@ -132,7 +94,7 @@ object Isos { timestamp = sigma.js.Isos.isoBigIntToLong.from(header.timestamp), nBits = sigma.js.Isos.isoBigIntToLong.from(header.nBits), height = header.height, - minerPk = isoGroupElement.from(header.minerPk), + minerPk = DataIsos.isoGroupElement.from(header.minerPk), votes = isoStringToColl.from(header.votes) ) } @@ -195,7 +157,7 @@ object Isos { val keys = js.Object.keys(x).sorted for ( k <- keys ) { val id = k.toInt.toByte - val c = isoHexStringToConstant.to(x.apply(id).get.get) + val c = DataIsos.isoHexStringToConstant.to(x.apply(id).get.get) map = map + (id -> c) } ContextExtension(map) @@ -204,7 +166,7 @@ object Isos { override def from(x: ContextExtension): contextExtensionMod.ContextExtension = { val res = new Object().asInstanceOf[contextExtensionMod.ContextExtension] x.values.foreach { case (k, v: Constant[_]) => - val hex = isoHexStringToConstant.from(v) + val hex = DataIsos.isoHexStringToConstant.from(v) res.update(k, hex) } res @@ -213,10 +175,10 @@ object Isos { implicit val isoUnsignedInput: Iso[inputsMod.UnsignedInput, UnsignedInput] = new Iso[inputsMod.UnsignedInput, UnsignedInput] { override def to(x: inputsMod.UnsignedInput): UnsignedInput = - new UnsignedInput(x.boxId.convertTo[ErgoBox.BoxId], isoContextExtension.to(x.extension)) + new UnsignedInput(DataIsos.isoBoxId.to(x.boxId), isoContextExtension.to(x.extension)) override def from(x: UnsignedInput): inputsMod.UnsignedInput = - inputsMod.UnsignedInput(x.boxId.convertTo[boxesMod.BoxId], isoContextExtension.from(x.extension)) + inputsMod.UnsignedInput(DataIsos.isoBoxId.from(x.boxId), isoContextExtension.from(x.extension)) } implicit val isoProverResult: Iso[proverResultMod.ProverResult, ProverResult] = new Iso[proverResultMod.ProverResult, ProverResult] { @@ -236,135 +198,17 @@ object Isos { implicit val isoSignedInput: Iso[inputsMod.SignedInput, Input] = new Iso[inputsMod.SignedInput, Input] { override def to(x: inputsMod.SignedInput): Input = - Input(x.boxId.convertTo[ErgoBox.BoxId], isoProverResult.to(x.spendingProof)) + Input(DataIsos.isoBoxId.to(x.boxId), isoProverResult.to(x.spendingProof)) override def from(x: Input): inputsMod.SignedInput = - inputsMod.SignedInput(x.boxId.convertTo[boxesMod.BoxId], isoProverResult.from(x.spendingProof)) + inputsMod.SignedInput(DataIsos.isoBoxId.from(x.boxId), isoProverResult.from(x.spendingProof)) } implicit val isoDataInput: Iso[inputsMod.DataInput, DataInput] = new Iso[inputsMod.DataInput, DataInput] { - override def to(x: inputsMod.DataInput): DataInput = DataInput(x.boxId.convertTo[ErgoBox.BoxId]) - - override def from(x: DataInput): inputsMod.DataInput = inputsMod.DataInput(x.boxId.convertTo[boxesMod.BoxId]) - } + override def to(x: inputsMod.DataInput): DataInput = + DataInput(DataIsos.isoBoxId.to(x.boxId)) - implicit val isoAmount: Iso[commonMod.Amount, Long] = new Iso[commonMod.Amount, Long] { - override def to(x: commonMod.Amount): Long = x.asInstanceOf[Any] match { - case s: String => BigInt(s).toLong - case _ => java.lang.Long.parseLong(x.asInstanceOf[js.BigInt].toString(10)) - } - override def from(x: Long): commonMod.Amount = x.toString - } - - implicit val isoToken: Iso[tokenMod.TokenAmount[commonMod.Amount], Token] = - new Iso[tokenMod.TokenAmount[commonMod.Amount], Token] { - override def to(x: tokenMod.TokenAmount[commonMod.Amount]): Token = - (Digest32Coll @@@ Colls.fromArray(Base16.decode(x.tokenId).get), isoAmount.to(x.amount)) - - override def from(x: Token): tokenMod.TokenAmount[commonMod.Amount] = - tokenMod.TokenAmount[commonMod.Amount](isoAmount.from(x._2), x._1.toHex) - } - - val isoTokenArray: Iso[js.Array[tokenMod.TokenAmount[commonMod.Amount]], Coll[Token]] = - new Iso[js.Array[tokenMod.TokenAmount[commonMod.Amount]], Coll[Token]] { - override def to(x: js.Array[tokenMod.TokenAmount[commonMod.Amount]]): Coll[Token] = { - sigma.js.Isos.isoArrayToColl(isoToken).to(x) - } - override def from(x: Coll[Token]): js.Array[tokenMod.TokenAmount[commonMod.Amount]] = { - sigma.js.Isos.isoArrayToColl(isoToken).from(x) - } - } - - val isoNonMandatoryRegisters: Iso[registersMod.NonMandatoryRegisters, AdditionalRegisters] = - new Iso[registersMod.NonMandatoryRegisters, AdditionalRegisters] { - override def to(x: registersMod.NonMandatoryRegisters): AdditionalRegisters = { - val regs = Seq( - x.R4 -> R4, - x.R5 -> R5, - x.R6 -> R6, - x.R7 -> R7, - x.R8 -> R8, - x.R9 -> R9 - ).collect { - case (regOpt, id) if regOpt.isDefined => id -> isoHexStringToConstant.to(regOpt.get) - } - Map(regs:_*) - } - override def from(regs: AdditionalRegisters): registersMod.NonMandatoryRegisters = { - def regHexOpt(t: NonMandatoryRegisterId): Option[HexString] = - regs.get(t).map(v => isoHexStringToConstant.from(v.asInstanceOf[Constant[SType]])) - - val resRegs = NonMandatoryRegisters() - regHexOpt(R4).foreach(resRegs.setR4(_)) - regHexOpt(R5).foreach(resRegs.setR5(_)) - regHexOpt(R6).foreach(resRegs.setR6(_)) - regHexOpt(R7).foreach(resRegs.setR7(_)) - regHexOpt(R8).foreach(resRegs.setR8(_)) - regHexOpt(R9).foreach(resRegs.setR9(_)) - resRegs - } - } - - implicit val isoBoxCandidate: Iso[boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters], ErgoBoxCandidate] = new Iso[boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters], ErgoBoxCandidate] { - override def to(x: boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters]): ErgoBoxCandidate = { - val ergoBoxCandidate = new ErgoBoxCandidate( - value = isoAmount.to(x.value), - ergoTree = { - val bytes = Base16.decode(x.ergoTree).get - ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes) - }, - x.creationHeight.toInt, - additionalTokens = isoTokenArray.to(x.assets), - additionalRegisters = isoNonMandatoryRegisters.to(x.additionalRegisters) - ) - ergoBoxCandidate - } - - override def from(x: ErgoBoxCandidate): boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters] = { - val ergoTree = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(x.ergoTree) - val ergoTreeStr = Base16.encode(ergoTree) - val assets = isoTokenArray.from(x.additionalTokens) - boxesMod.BoxCandidate[commonMod.Amount, NonMandatoryRegisters]( - ergoTree = ergoTreeStr, - value = isoAmount.from(x.value), - assets = assets, - creationHeight = x.creationHeight, - additionalRegisters = isoNonMandatoryRegisters.from(x.additionalRegisters) - ) - } - } - - val isoBox: Iso[Box[commonMod.Amount, NonMandatoryRegisters], ErgoBox] = new Iso[Box[commonMod.Amount, NonMandatoryRegisters], ErgoBox] { - override def to(x: Box[commonMod.Amount, NonMandatoryRegisters]): ErgoBox = { - val ergoBox = new ErgoBox( - value = isoAmount.to(x.value), - ergoTree = { - val bytes = Base16.decode(x.ergoTree).get - ErgoTreeSerializer.DefaultSerializer.deserializeErgoTree(bytes) - }, - creationHeight = x.creationHeight.toInt, - additionalTokens = isoTokenArray.to(x.assets), - additionalRegisters = isoNonMandatoryRegisters.to(x.additionalRegisters), - transactionId = ModifierId @@ x.transactionId, - index = x.index.toShort - ) - ergoBox - } - - override def from(x: ErgoBox): Box[commonMod.Amount, NonMandatoryRegisters] = { - val ergoTree = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(x.ergoTree) - val ergoTreeStr = Base16.encode(ergoTree) - val assets = isoTokenArray.from(x.additionalTokens) - Box[commonMod.Amount, NonMandatoryRegisters]( - boxId = Base16.encode(x.id), - ergoTree = ergoTreeStr, - value = isoAmount.from(x.value), - assets = assets, - creationHeight = x.creationHeight, - additionalRegisters = isoNonMandatoryRegisters.from(x.additionalRegisters), - transactionId = x.transactionId, - index = x.index - ) - } + override def from(x: DataInput): inputsMod.DataInput = + inputsMod.DataInput(DataIsos.isoBoxId.from(x.boxId)) } val isoEIP12UnsignedInput: Iso[inputsMod.EIP12UnsignedInput, ExtendedInputBox] = @@ -380,12 +224,12 @@ object Isos { transactionId = x.transactionId, index = x.index ) - val ergoBox = isoBox.to(box) + val ergoBox = sigma.js.Box.isoBox.to(box) val extendedInputBox = ExtendedInputBox(ergoBox, isoContextExtension.to(x.extension)) extendedInputBox } override def from(x: ExtendedInputBox): inputsMod.EIP12UnsignedInput = { - val box = isoBox.from(x.box) + val box = sigma.js.Box.isoBox.from(x.box) val ext = isoContextExtension.from(x.extension) inputsMod.EIP12UnsignedInput( boxId = box.boxId, @@ -407,7 +251,7 @@ object Isos { new UnsignedErgoLikeTransaction( inputs = sigma.js.Isos.isoArrayToIndexed(isoUnsignedInput).to(a.inputs), dataInputs = sigma.js.Isos.isoArrayToIndexed(isoDataInput).to(a.dataInputs), - outputCandidates = sigma.js.Isos.isoArrayToIndexed(isoBoxCandidate).to(a.outputs), + outputCandidates = sigma.js.Isos.isoArrayToIndexed(DataIsos.isoBoxCandidate).to(a.outputs), ) } @@ -415,7 +259,7 @@ object Isos { UnsignedTransaction( inputs = sigma.js.Isos.isoArrayToIndexed(isoUnsignedInput).from(b.inputs), dataInputs = sigma.js.Isos.isoArrayToIndexed(isoDataInput).from(b.dataInputs), - outputs = sigma.js.Isos.isoArrayToIndexed(isoBoxCandidate).from(b.outputCandidates) + outputs = sigma.js.Isos.isoArrayToIndexed(DataIsos.isoBoxCandidate).from(b.outputCandidates) ) } } @@ -426,14 +270,14 @@ object Isos { new ErgoLikeTransaction( inputs = sigma.js.Isos.isoArrayToIndexed(isoSignedInput).to(a.inputs), dataInputs = sigma.js.Isos.isoArrayToIndexed(isoDataInput).to(a.dataInputs), - outputCandidates = sigma.js.Isos.isoArrayToIndexed(isoBox).to(a.outputs), + outputCandidates = sigma.js.Isos.isoArrayToIndexed(sigma.js.Box.isoBox).to(a.outputs), ) } override def from(tx: ErgoLikeTransaction): SignedTransaction = { val inputs = sigma.js.Isos.isoArrayToIndexed(isoSignedInput).from(tx.inputs) val dataInputs = sigma.js.Isos.isoArrayToIndexed(isoDataInput).from(tx.dataInputs) - val outputs = sigma.js.Isos.isoArrayToIndexed(isoBox).from(tx.outputs) + val outputs = sigma.js.Isos.isoArrayToIndexed(sigma.js.Box.isoBox).from(tx.outputs) SignedTransaction(dataInputs, tx.id, inputs, outputs) } } diff --git a/sdk/js/src/main/scala/org/ergoplatform/sdk/js/ProverBuilder.scala b/sdk/js/src/main/scala/org/ergoplatform/sdk/js/ProverBuilder.scala index 12ecf1d03f..7ab95c187e 100644 --- a/sdk/js/src/main/scala/org/ergoplatform/sdk/js/ProverBuilder.scala +++ b/sdk/js/src/main/scala/org/ergoplatform/sdk/js/ProverBuilder.scala @@ -6,6 +6,7 @@ import org.ergoplatform.sdk.SecretString import scala.scalajs.js import scala.scalajs.js.annotation.JSExportTopLevel import Isos._ +import sigma.data.js.{Isos => DataIsos} import sigma.eval.SigmaDsl /** Equivalent of [[sdk.ProverBuilder]] available from JS. @@ -66,10 +67,10 @@ class ProverBuilder(parameters: BlockchainParameters, network: Byte) extends js. */ def withDHTSecret(g: String, h: String, u: String, v: String, x: js.BigInt): ProverBuilder = { _builder.withDHTData( - isoStringToGroupElement.to(g), - isoStringToGroupElement.to(h), - isoStringToGroupElement.to(u), - isoStringToGroupElement.to(v), + DataIsos.isoStringToGroupElement.to(g), + DataIsos.isoStringToGroupElement.to(h), + DataIsos.isoStringToGroupElement.to(u), + DataIsos.isoStringToGroupElement.to(v), SigmaDsl.toBigInteger(sigma.js.Isos.isoBigInt.to(x)) ) this diff --git a/sdk/js/src/main/scala/org/ergoplatform/sdk/js/SigmaProver.scala b/sdk/js/src/main/scala/org/ergoplatform/sdk/js/SigmaProver.scala index 0a6aca4830..693c0717bb 100644 --- a/sdk/js/src/main/scala/org/ergoplatform/sdk/js/SigmaProver.scala +++ b/sdk/js/src/main/scala/org/ergoplatform/sdk/js/SigmaProver.scala @@ -51,8 +51,8 @@ class SigmaProver(_prover: sdk.SigmaProver) extends js.Object { val unreducedTx = sdk.UnreducedTransaction( unsignedTx = isoUnsignedTransaction.to(unsignedTx), boxesToSpend = sigma.js.Isos.isoArrayToIndexed(isoEIP12UnsignedInput).to(boxesToSpend), - dataInputs = sigma.js.Isos.isoArrayToIndexed(isoBox).to(dataInputs), - tokensToBurn = sigma.js.Isos.isoArrayToIndexed(isoToken.andThen(sdk.SdkIsos.isoErgoTokenToPair.inverse)).to(tokensToBurn) + dataInputs = sigma.js.Isos.isoArrayToIndexed(sigma.js.Box.isoBox).to(dataInputs), + tokensToBurn = sigma.js.Isos.isoArrayToIndexed(sigma.data.js.Isos.isoToken.andThen(sdk.SdkIsos.isoErgoTokenToPair.inverse)).to(tokensToBurn) ) val ctx = isoBlockchainStateContext.to(stateCtx) val reducedTx = _prover.reduce(ctx, unreducedTx, baseCost) diff --git a/sdk/js/src/test/scala/org/ergoplatform/sdk/js/IsosSpec.scala b/sdk/js/src/test/scala/org/ergoplatform/sdk/js/IsosSpec.scala index a366e33d3c..a040731b20 100644 --- a/sdk/js/src/test/scala/org/ergoplatform/sdk/js/IsosSpec.scala +++ b/sdk/js/src/test/scala/org/ergoplatform/sdk/js/IsosSpec.scala @@ -10,7 +10,7 @@ import sigma.data.Iso import sigma.interpreter.{ContextExtension, ProverResult} import sigma.js.AvlTree import sigma.{Coll, GroupElement} - +import sigma.data.js.{Isos => DataIsos} import scala.scalajs.js class IsosSpec extends IsosSpecBase with sdk.generators.ObjectGenerators { @@ -31,19 +31,19 @@ class IsosSpec extends IsosSpecBase with sdk.generators.ObjectGenerators { property("Iso.isoStringToGroupElement") { forAll() { (bytes: GroupElement) => - roundtrip(Isos.isoStringToGroupElement)(bytes) + roundtrip(DataIsos.isoStringToGroupElement)(bytes) } } property("Iso.isoBoxId") { forAll(boxIdGen) { (id: BoxId) => - roundtrip(Isos.isoBoxId)(id) + roundtrip(DataIsos.isoBoxId)(id) } } property("Iso.isoHexStringToConstant") { forAll(constantGen, MinSuccessful(100)) { (c: Constant[SType]) => - roundtrip(Isos.isoHexStringToConstant)(c) + roundtrip(DataIsos.isoHexStringToConstant)(c) } } @@ -115,20 +115,20 @@ class IsosSpec extends IsosSpecBase with sdk.generators.ObjectGenerators { property("Iso.isoAmount") { forAll { (c: Long) => - roundtrip(Isos.isoAmount)(c) - Isos.isoAmount.to(js.BigInt(c.toString)) shouldBe c + roundtrip(DataIsos.isoAmount)(c) + DataIsos.isoAmount.to(js.BigInt(c.toString)) shouldBe c } } property("Iso.isoToken") { forAll(tokenIdGen, Arbitrary.arbLong.arbitrary) { (id: TokenId, amount: Long) => - roundtrip(Isos.isoToken)((id, amount)) + roundtrip(DataIsos.isoToken)((id, amount)) } } property("Iso.isoTokenArray") { forAll(ergoBoxTokens(tokensGen.sample.get)) { tokens => - roundtrip(Isos.isoTokenArray)(tokens) + roundtrip(DataIsos.isoTokenArray)(tokens) } } @@ -140,19 +140,19 @@ class IsosSpec extends IsosSpecBase with sdk.generators.ObjectGenerators { property("Iso.isoNonMandatoryRegisters") { forAll(additionalRegistersGen) { (x: AdditionalRegisters) => - roundtrip(Isos.isoNonMandatoryRegisters)(x) + roundtrip(DataIsos.isoNonMandatoryRegisters)(x) } } property("Iso.isoBoxCandidate") { forAll { (box: ErgoBoxCandidate) => - roundtrip(Isos.isoBoxCandidate)(box) + roundtrip(DataIsos.isoBoxCandidate)(box) } } property("Iso.isoBox") { forAll { (b: ErgoBox) => - roundtrip(Isos.isoBox)(b) + roundtrip(sigma.js.Box.isoBox)(b) } } From 1177d09640f4db75708edc70cb8bff805bd6de4c Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 2 May 2024 18:25:37 +0100 Subject: [PATCH 34/38] i956-box-in-register: tests for Box Value toHex/fromHex --- core/js/src/main/scala/sigma/js/Value.scala | 261 -------------------- data/js/src/main/scala/sigma/js/Box.scala | 12 +- data/js/src/main/scala/sigma/js/Value.scala | 17 +- sigma-js/package-lock.json | 4 +- sigma-js/sigmastate-js.d.ts | 10 +- sigma-js/tests/js/Box.spec.js | 29 +++ 6 files changed, 58 insertions(+), 275 deletions(-) delete mode 100644 core/js/src/main/scala/sigma/js/Value.scala create mode 100644 sigma-js/tests/js/Box.spec.js diff --git a/core/js/src/main/scala/sigma/js/Value.scala b/core/js/src/main/scala/sigma/js/Value.scala deleted file mode 100644 index 13b63c2abc..0000000000 --- a/core/js/src/main/scala/sigma/js/Value.scala +++ /dev/null @@ -1,261 +0,0 @@ -package sigma -package js - -import scorex.util.Extensions.{IntOps, LongOps} -import scorex.util.encode.Base16 -import sigma.ast.SType -import sigma.crypto.Platform -import sigma.data._ -import sigma.js.Value.toRuntimeData -import sigma.serialization.{CoreDataSerializer, CoreSerializer} -import sigma.util.Extensions.BigIntOps -import sigma.{Coll, Colls, Evaluation} - -import java.math.BigInteger -import scala.scalajs.js -import scala.scalajs.js.annotation.JSExportTopLevel - -/** - * This class is used to represent any valid value of ErgoScript language. - * Any such value comes equipped with {@link Type} descriptor. - * Note, there is a distinction between JS types and ErgoScript types. - * Each Value instance represents the concrete ErgoScript type given by `tpe`. - * The implementation is based on the pre-defined mapping between JS and ES types. - * This mapping is applied recursively and is given by the following: - * - * JS type | ErgoScript Type - * -------------------------------------- - * Number | Byte - * Number | Short - * Number | Int - * BigInt | Long - * BigInt | BigInt - * array [A, B] | (A, B) - pair - * array [a1, a2 ..] | Coll[A] - collection - * - * @param data JS value wrapped in this value - * @param tpe type descriptor of the ErgoScript type - */ -@JSExportTopLevel("Value") -class Value(val data: Any, val tpe: Type) extends js.Object { - - /** Get Sigma runtime value which can be passed to interpreter, saved in register and - * [[sigma.ast.Constant]] nodes. - */ - final def runtimeData: Any = toRuntimeData(data, tpe.rtype) - - /** - * Encode this value as Base16 hex string. - * 1) it transforms this value into {@link sigma.ast.ConstantNode} of sigma. - * 2) it serializes the constant into byte array using {@link sigmastate.serialization.ConstantSerializer} - * 3) the bytes are encoded using Base16 encoder into string - * - * @return hex string of serialized bytes - */ - def toHex(): String = { - val stype = Evaluation.rtypeToSType(tpe.rtype) - val value = runtimeData.asInstanceOf[SType#WrappedType] - val w = CoreSerializer.startWriter() - w.putType(stype) - CoreDataSerializer.serialize(value, stype, w) - Base16.encode(w.toBytes) - } -} - -@JSExportTopLevel("Value$") -object Value extends js.Object { - /** Maximal positive value of ES type Long */ - val MaxLong = js.BigInt("0x7fffffffffffffff") - - /** Minimal negative value of ES type Long */ - val MinLong = -js.BigInt("0x8000000000000000") - - /** Helper method to get Sigma runtime value which can be passed to interpreter, saved - * in register and [[sigma.ast.Constant]] nodes. - */ - final private[js] def toRuntimeData(data: Any, rtype: RType[_]): Any = rtype match { - case sigma.BooleanType => data - case sigma.ByteType | sigma.ShortType | sigma.IntType => data - case sigma.LongType => java.lang.Long.parseLong(data.asInstanceOf[js.BigInt].toString(10)) - case sigma.BigIntRType => - val v = data.asInstanceOf[js.BigInt] - CBigInt(new BigInteger(v.toString(16), 16)) - case sigma.GroupElementRType => - val ge = data.asInstanceOf[GroupElement] - CGroupElement(ge.point) - case sigma.SigmaPropRType => - val p = data.asInstanceOf[SigmaProp] - CSigmaProp(p.sigmaBoolean) - case sigma.AvlTreeRType => - val t = data.asInstanceOf[AvlTree] - AvlTree.isoAvlTree.to(t) - case ct: CollType[a] => - val xs = data.asInstanceOf[js.Array[Any]] - implicit val cT = ct.tItem.classTag - val items = xs.map(x => toRuntimeData(x, ct.tItem).asInstanceOf[a]).toArray[a] - Colls.fromItems(items:_*)(ct.tItem) - case pt: PairType[a, b] => - val p = data.asInstanceOf[js.Array[Any]] - val x = toRuntimeData(p(0), pt.tFst).asInstanceOf[a] - val y = toRuntimeData(p(1), pt.tSnd).asInstanceOf[b] - (x, y) - case sigma.UnitType => data - case _ => - throw new IllegalArgumentException(s"Unsupported type $rtype") - } - - /** Helper method to extract JS data value from Sigma runtime value. - * This should be inverse to `toRuntimeData`. - * - * @param value runtime value of type given by `rtype` - * @param rtype type descriptor of Sigma runtime value - */ - final def fromRuntimeData(value: Any, rtype: RType[_]): Any = rtype match { - case sigma.BooleanType => value - case sigma.ByteType | sigma.ShortType | sigma.IntType => value - case sigma.LongType => js.BigInt(value.asInstanceOf[Long].toString) - case sigma.BigIntRType => - val hex = value.asInstanceOf[sigma.BigInt].toBigInteger.toString(10) - js.BigInt(hex) - case sigma.GroupElementRType => - val point = value.asInstanceOf[CGroupElement].wrappedValue.asInstanceOf[Platform.Ecp] - new GroupElement(point) - case sigma.SigmaPropRType => - new SigmaProp(value.asInstanceOf[CSigmaProp].wrappedValue) - case sigma.AvlTreeRType => - AvlTree.isoAvlTree.from(value.asInstanceOf[CAvlTree]) - case ct: CollType[a] => - val arr = value.asInstanceOf[Coll[a]].toArray - js.Array(arr.map(x => fromRuntimeData(x, ct.tItem)):_*) - case pt: PairType[a, b] => - val p = value.asInstanceOf[(a, b)] - js.Array(fromRuntimeData(p._1, pt.tFst), fromRuntimeData(p._2, pt.tSnd)) - case sigma.UnitType => value - case _ => - throw new IllegalArgumentException(s"Unsupported type $rtype") - } - - /** Helper method to check validity of JS data value against the given runtime type. - * - * @param data js value - * @param rtype type descriptor of Sigma runtime value - */ - final private def checkJsData[T](data: T, rtype: RType[_]): Any = rtype match { - case sigma.ByteType => data.asInstanceOf[Int].toByteExact - case sigma.ShortType => data.asInstanceOf[Int].toShortExact - case sigma.IntType => data.asInstanceOf[Int].toLong.toIntExact - case sigma.LongType => - val n = data.asInstanceOf[js.BigInt] - if (n < MinLong || n > MaxLong) - throw new ArithmeticException(s"value $n is out of long range") - n - case sigma.BigIntRType => - data.asInstanceOf[js.BigInt] - case sigma.GroupElementRType => - data.asInstanceOf[GroupElement] - case sigma.SigmaPropRType => - data.asInstanceOf[SigmaProp] - case PairType(l, r) => data match { - case arr: js.Array[Any @unchecked] => - checkJsData(arr(0), l) - checkJsData(arr(1), r) - data - case _ => - throw new ArithmeticException(s"$data cannot represent pair value") - } - case CollType(elemType) => data match { - case arr: js.Array[Any @unchecked] => - arr.foreach(x => checkJsData(x, elemType)) - data - case _ => - throw new ArithmeticException(s"$data cannot represent Coll value") - } - case _ => - throw new IllegalArgumentException(s"Unsupported type $rtype") - } - - /** Create Byte value from JS number. */ - def ofByte(n: Int): Value = { - checkJsData(n, Type.Byte.rtype) - new Value(n, Type.Byte) - } - - /** Create Short value from JS number. */ - def ofShort(n: Int): Value = { - checkJsData(n, Type.Short.rtype) - new Value(n, Type.Short) - } - - /** Create Int value from JS number. */ - def ofInt(n: Int): Value = { - checkJsData(n, Type.Int.rtype) - new Value(n, Type.Int) - } - - /** Create Long value from JS BigInt. */ - def ofLong(n: js.BigInt): Value = { - checkJsData(n, Type.Long.rtype) - new Value(n, Type.Long) - } - - /** Create BigInt value from JS BigInt. */ - def ofBigInt(n: js.BigInt): Value = { - checkJsData(n, Type.BigInt.rtype) - new Value(n, Type.BigInt) - } - - /** Creates a Value of GroupElement type from [[sigmastate.crypto.Platform.Point]] hex. - * @param pointHex hex of ASN representation of [[sigmastate.crypto.Platform.Point]] - */ - def ofGroupElement(pointHex: String): Value = { - val ge = GroupElement.fromPointHex(pointHex) - new Value(ge, Type.GroupElement) - } - - /** Creates a Value of SigmaProp type from [[sigmastate.crypto.Platform.Point]] hex. - * @param pointHex hex of ASN representation of [[sigmastate.crypto.Platform.Point]] - */ - def ofSigmaProp(pointHex: String): Value = { - val sp = SigmaProp.fromPointHex(pointHex) - new Value(sp, Type.SigmaProp) - } - - /** Create Pair value from two values. */ - def pairOf(l: Value, r: Value): Value = { - val data = js.Array(l.data, r.data) // the l and r data have been validated - new Value(data, Type.pairType(l.tpe, r.tpe)) - } - - /** Create Coll value from array and element type descriptor. - * @param items collection elements which should be valid JS representation of `elemType` - * @param elemType descriptor of types for collection elements - */ - def collOf(items: js.Array[Any], elemType: Type): Value = { - val t = Type.collType(elemType) - checkJsData(items, t.rtype) - new Value(items, t) - } - - /** - * Creates Value from hex encoded serialized bytes of Constant values. - *

- * In order to create Value you need to provide both value instance and - * Type descriptor. This is similar to how values are represented in sigma - * ConstantNode. Each ConstantNode also have value instance and `tpe: SType` - * descriptor. - * @param hex the string is obtained as hex encoding of serialized ConstantNode. - * (The bytes obtained by ConstantSerializer in sigma) - * @return new deserialized Value instance containing: - * - suitable JS value in its `data` field - * - and [[Type]] descriptor in its `tpe` field - */ - def fromHex(hex: String): Value = { - val bytes = Base16.decode(hex).fold(t => throw t, identity) - val r = CoreSerializer.startReader(bytes) - val stype = r.getType() - val value = CoreDataSerializer.deserialize(stype, r) - val rtype = Evaluation.stypeToRType(stype) - val jsvalue = Value.fromRuntimeData(value, rtype) - new Value(jsvalue, new Type(rtype)) - } -} diff --git a/data/js/src/main/scala/sigma/js/Box.scala b/data/js/src/main/scala/sigma/js/Box.scala index 209e15d489..70155633d5 100644 --- a/data/js/src/main/scala/sigma/js/Box.scala +++ b/data/js/src/main/scala/sigma/js/Box.scala @@ -16,15 +16,15 @@ import scala.scalajs.js.annotation.JSExportTopLevel /** Equivalent of [[sigma.Box]] available from JS. */ @JSExportTopLevel("Box") -class Box(val box: FBox[Amount, NonMandatoryRegisters]) extends js.Object { -} +class Box(val box: FBox[Amount, NonMandatoryRegisters]) extends js.Object -@JSExportTopLevel("Box$") object Box extends js.Object { + /** Represents a box in Fleet SDK. */ + type FleetBox = FBox[commonMod.Amount, NonMandatoryRegisters] /** Converts Fleet box to ErgoBox and back. */ - val isoBox: Iso[FBox[commonMod.Amount, NonMandatoryRegisters], ErgoBox] = new Iso[FBox[commonMod.Amount, NonMandatoryRegisters], ErgoBox] { - override def to(x: FBox[commonMod.Amount, NonMandatoryRegisters]): ErgoBox = { + val isoBox: Iso[FleetBox, ErgoBox] = new Iso[FleetBox, ErgoBox] { + override def to(x: FleetBox): ErgoBox = { val ergoBox = new ErgoBox( value = isoAmount.to(x.value), ergoTree = { @@ -40,7 +40,7 @@ object Box extends js.Object { ergoBox } - override def from(x: ErgoBox): FBox[commonMod.Amount, NonMandatoryRegisters] = { + override def from(x: ErgoBox): FleetBox = { val ergoTree = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(x.ergoTree) val ergoTreeStr = Base16.encode(ergoTree) val assets = isoTokenArray.from(x.additionalTokens) diff --git a/data/js/src/main/scala/sigma/js/Value.scala b/data/js/src/main/scala/sigma/js/Value.scala index 785f9e04db..fea6cd9b8b 100644 --- a/data/js/src/main/scala/sigma/js/Value.scala +++ b/data/js/src/main/scala/sigma/js/Value.scala @@ -7,9 +7,10 @@ import sigma.ast.SType import sigma.crypto.Platform import sigma.data._ import sigma.js.Value.toRuntimeData -import sigma.serialization.{CoreSerializer, DataSerializer} +import sigma.serialization.{CoreDataSerializer, CoreSerializer, DataSerializer, SigmaSerializer} import sigma.util.Extensions.BigIntOps import sigma.{Coll, Colls, Evaluation} +import sigmastate.fleetSdkCommon.distEsmTypesBoxesMod.{Box => FBox} import java.math.BigInteger import scala.scalajs.js @@ -55,7 +56,7 @@ class Value(val data: Any, val tpe: Type) extends js.Object { def toHex(): String = { val stype = Evaluation.rtypeToSType(tpe.rtype) val value = runtimeData.asInstanceOf[SType#WrappedType] - val w = CoreSerializer.startWriter() + val w = SigmaSerializer.startWriter() w.putType(stype) DataSerializer.serialize(value, stype, w) Base16.encode(w.toBytes) @@ -128,7 +129,8 @@ object Value extends js.Object { case sigma.AvlTreeRType => AvlTree.isoAvlTree.from(value.asInstanceOf[CAvlTree]) case sigma.BoxRType => - AvlTree.isoAvlTree.from(value.asInstanceOf[CAvlTree]) + val fleetBox = Box.isoBox.from(value.asInstanceOf[CBox].wrappedValue) + new Box(fleetBox) case ct: CollType[a] => val arr = value.asInstanceOf[Coll[a]].toArray js.Array(arr.map(x => fromRuntimeData(x, ct.tItem)):_*) @@ -225,6 +227,13 @@ object Value extends js.Object { new Value(sp, Type.SigmaProp) } + /** Creates a Value of Box type from a [[FBox]] instance. + * @param fleetBox a Fleet box to be wrapped in a [[Value]] + */ + def ofBox(fleetBox: Box.FleetBox): Value = { + new Value(new Box(fleetBox), Type.Box) + } + /** Create Pair value from two values. */ def pairOf(l: Value, r: Value): Value = { val data = js.Array(l.data, r.data) // the l and r data have been validated @@ -256,7 +265,7 @@ object Value extends js.Object { */ def fromHex(hex: String): Value = { val bytes = Base16.decode(hex).fold(t => throw t, identity) - val r = CoreSerializer.startReader(bytes) + val r = SigmaSerializer.startReader(bytes) val stype = r.getType() val value = DataSerializer.deserialize(stype, r) val rtype = Evaluation.stypeToRType(stype) diff --git a/sigma-js/package-lock.json b/sigma-js/package-lock.json index 893a0ee141..c34f802f6e 100644 --- a/sigma-js/package-lock.json +++ b/sigma-js/package-lock.json @@ -1,12 +1,12 @@ { "name": "sigmastate-js", - "version": "0.3.0", + "version": "0.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "sigmastate-js", - "version": "0.3.0", + "version": "0.4.0", "license": "MIT", "dependencies": { "@fleet-sdk/common": "0.1.3", diff --git a/sigma-js/sigmastate-js.d.ts b/sigma-js/sigmastate-js.d.ts index b70ca39258..53baa3b026 100644 --- a/sigma-js/sigmastate-js.d.ts +++ b/sigma-js/sigmastate-js.d.ts @@ -1,7 +1,7 @@ declare module "sigmastate-js/main" { import { Amount, - Box, + Box as FBox, EIP12UnsignedInput, NonMandatoryRegisters, SignedTransaction, TokenAmount, UnsignedTransaction @@ -173,6 +173,10 @@ declare module "sigmastate-js/main" { valueLengthOpt: number | undefined; } + export declare class Box { + box: FBox; + } + export declare class PreHeader { /** Block version, to be increased on every soft and hardfork. */ version: number; @@ -301,6 +305,8 @@ declare module "sigmastate-js/main" { static ofSigmaProp(pointHex: string): Value; + static ofBox(box: FBox): Value; + static pairOf(left: Value, right: Value): Value<[R, L]>; static collOf(items: T[], elemType: Type): Value; @@ -498,7 +504,7 @@ declare module "sigmastate-js/main" { stateCtx: BlockchainStateContext, unsignedTx: UnsignedTransaction, boxesToSpend: EIP12UnsignedInput[], - dataInputs: Box[], + dataInputs: FBox[], tokensToBurn: TokenAmount[], baseCost: number): ReducedTransaction; diff --git a/sigma-js/tests/js/Box.spec.js b/sigma-js/tests/js/Box.spec.js new file mode 100644 index 0000000000..5782507ae4 --- /dev/null +++ b/sigma-js/tests/js/Box.spec.js @@ -0,0 +1,29 @@ +const {Box$, Value$} = require("sigmastate-js/main"); + +describe("Box", () => { + it("should deserialize from hex", () => { + let boxHex = "63b96000d1968302010100ff83020193040204020100c0843d000401010e32297000800b80f1d56c809a8c6affbed864b87f007f6f007f00ac00018c01c4fdff011088807f0100657f00f9ab0101ff6d6505a4a7b5a2e7a4a4dd3a05feffffffffffffffff01003bd5c630803cfff6c1ff7f7fb980ff136afc011f8080b8b04ad4dbda2d7f4e01" + let deserialized = Value$.fromHex(boxHex); + // console.log(b.data) + let expected = { + additionalRegisters: { + R4: '0101', + R5: '0e32297000800b80f1d56c809a8c6affbed864b87f007f6f007f00ac00018c01c4fdff011088807f0100657f00f9ab0101ff6d65', + R6: '05a4a7b5a2e7a4a4dd3a', + R7: '05feffffffffffffffff01' + }, + assets: [], + boxId: '3a0089be265460e29ca47d26e5b55a6f3e3ffaf5b4aed941410a2437913848ad', + creationHeight: 1000000, + ergoTree: '00d1968302010100ff83020193040204020100', + index: 1, + transactionId: '003bd5c630803cfff6c1ff7f7fb980ff136afc011f8080b8b04ad4dbda2d7f4e', + value: '12345' + } + let fleetBox = deserialized.data.box + expect(fleetBox).toEqual(expected) + + let newBoxValue = Value$.ofBox(fleetBox) + expect(newBoxValue.toHex()).toEqual(boxHex) + }); +}); \ No newline at end of file From 42e79d7887d71904d5c6d13ea8c943d87997628b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Thu, 2 May 2024 18:34:48 +0100 Subject: [PATCH 35/38] i956-box-in-register: cleanup --- sigma-js/tests/js/Box.spec.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sigma-js/tests/js/Box.spec.js b/sigma-js/tests/js/Box.spec.js index 5782507ae4..24238013ba 100644 --- a/sigma-js/tests/js/Box.spec.js +++ b/sigma-js/tests/js/Box.spec.js @@ -1,10 +1,9 @@ const {Box$, Value$} = require("sigmastate-js/main"); describe("Box", () => { - it("should deserialize from hex", () => { + it("should serialize from/to hex", () => { let boxHex = "63b96000d1968302010100ff83020193040204020100c0843d000401010e32297000800b80f1d56c809a8c6affbed864b87f007f6f007f00ac00018c01c4fdff011088807f0100657f00f9ab0101ff6d6505a4a7b5a2e7a4a4dd3a05feffffffffffffffff01003bd5c630803cfff6c1ff7f7fb980ff136afc011f8080b8b04ad4dbda2d7f4e01" let deserialized = Value$.fromHex(boxHex); - // console.log(b.data) let expected = { additionalRegisters: { R4: '0101', From 83a7e701445c53918c877c01d1a93eb5d1d84ac1 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 3 May 2024 21:09:37 +0100 Subject: [PATCH 36/38] i956-box-in-register: Iso ScalaDoc + imports cleanup --- core/js/src/main/scala/sigma/js/Isos.scala | 3 +++ .../src/main/scala/sigma/data/Iso.scala | 10 +++++-- .../src/main/scala/sigma/data/js/Isos.scala | 16 ++++++------ data/js/src/main/scala/sigma/js/Value.scala | 2 +- .../scala/org/ergoplatform/sdk/js/Isos.scala | 26 +++++++------------ 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/core/js/src/main/scala/sigma/js/Isos.scala b/core/js/src/main/scala/sigma/js/Isos.scala index b28a3337b8..767a358d62 100644 --- a/core/js/src/main/scala/sigma/js/Isos.scala +++ b/core/js/src/main/scala/sigma/js/Isos.scala @@ -8,6 +8,9 @@ import scala.reflect.ClassTag import scala.scalajs.js import scala.scalajs.js.JSConverters.JSRichOption +/** Definitions of isomorphisms for sigma-core module. + * @see sigma.data.Iso + */ object Isos { implicit def isoUndefOr[A, B](implicit iso: Iso[A, B]): Iso[js.UndefOr[A], Option[B]] = new Iso[js.UndefOr[A], Option[B]] { diff --git a/core/shared/src/main/scala/sigma/data/Iso.scala b/core/shared/src/main/scala/sigma/data/Iso.scala index 9b90d63bb0..0e463bdd04 100644 --- a/core/shared/src/main/scala/sigma/data/Iso.scala +++ b/core/shared/src/main/scala/sigma/data/Iso.scala @@ -7,14 +7,20 @@ import sigma.{Coll, Colls} /** Type-class of isomorphisms between types. * Isomorphism between two types `A` and `B` essentially say that both types * represents the same information (entity) but in a different way. + * + * Each isomorphism defined by two functions: + * - `to: A => B` - conversion from `A` to `B` + * - `from: B => A` - conversion from `B` to `A` + * *

- * The information is not lost so that both are true: + * such that the information is not lost during conversion, so that both are true: * 1) a == from(to(a)) * 2) b == to(from(b)) *

* It is used to define type-full conversions: * - different conversions between Java and Scala data types. - * - conversion between Ergo representations and generated API representations + * - conversion between internal Ergo representations and API representations + * - conversions between exported JS classes and internal Ergo representations */ abstract class Iso[A, B] { def to(a: A): B diff --git a/data/js/src/main/scala/sigma/data/js/Isos.scala b/data/js/src/main/scala/sigma/data/js/Isos.scala index 95bbce8bbe..22300b1fd8 100644 --- a/data/js/src/main/scala/sigma/data/js/Isos.scala +++ b/data/js/src/main/scala/sigma/data/js/Isos.scala @@ -1,15 +1,9 @@ package sigma.data.js -import org.ergoplatform.{ErgoBox, ErgoBoxCandidate} import org.ergoplatform.ErgoBox._ +import org.ergoplatform.{ErgoBox, ErgoBoxCandidate} import scorex.crypto.authds.ADKey -import scorex.util.ModifierId import scorex.util.encode.Base16 -import sigma.{Coll, Colls} -import sigmastate.fleetSdkCommon.distEsmTypesBoxesMod.{Box => FBox} -import sigmastate.fleetSdkCommon.distEsmTypesCommonMod.{Amount, HexString} -import sigmastate.fleetSdkCommon.distEsmTypesRegistersMod.NonMandatoryRegisters -import sigmastate.fleetSdkCommon.{distEsmTypesBoxesMod => boxesMod, distEsmTypesCommonMod => commonMod, distEsmTypesRegistersMod => registersMod, distEsmTypesTokenMod => tokenMod} import sigma.Extensions._ import sigma.ast.syntax.GroupElementConstant import sigma.ast.{Constant, GroupElementConstant, SType} @@ -17,10 +11,16 @@ import sigma.data.Iso.isoStringToArray import sigma.data.{CGroupElement, Digest32Coll, Iso} import sigma.js.GroupElement import sigma.serialization.{ErgoTreeSerializer, ValueSerializer} +import sigma.{Coll, Colls} +import sigmastate.fleetSdkCommon.distEsmTypesCommonMod.HexString +import sigmastate.fleetSdkCommon.distEsmTypesRegistersMod.NonMandatoryRegisters +import sigmastate.fleetSdkCommon.{distEsmTypesBoxesMod => boxesMod, distEsmTypesCommonMod => commonMod, distEsmTypesRegistersMod => registersMod, distEsmTypesTokenMod => tokenMod} import scala.scalajs.js -/** Definitions of isomorphisms for sigma-data module. */ +/** Definitions of isomorphisms for sigma-data module. + * @see sigma.data.Iso + */ object Isos { val isoStringToGroupElement: Iso[String, sigma.GroupElement] = new Iso[String, sigma.GroupElement] { diff --git a/data/js/src/main/scala/sigma/js/Value.scala b/data/js/src/main/scala/sigma/js/Value.scala index fea6cd9b8b..a65156bd43 100644 --- a/data/js/src/main/scala/sigma/js/Value.scala +++ b/data/js/src/main/scala/sigma/js/Value.scala @@ -7,7 +7,7 @@ import sigma.ast.SType import sigma.crypto.Platform import sigma.data._ import sigma.js.Value.toRuntimeData -import sigma.serialization.{CoreDataSerializer, CoreSerializer, DataSerializer, SigmaSerializer} +import sigma.serialization.{DataSerializer, SigmaSerializer} import sigma.util.Extensions.BigIntOps import sigma.{Coll, Colls, Evaluation} import sigmastate.fleetSdkCommon.distEsmTypesBoxesMod.{Box => FBox} diff --git a/sdk/js/src/main/scala/org/ergoplatform/sdk/js/Isos.scala b/sdk/js/src/main/scala/org/ergoplatform/sdk/js/Isos.scala index f4085cf2a9..0f50a52686 100644 --- a/sdk/js/src/main/scala/org/ergoplatform/sdk/js/Isos.scala +++ b/sdk/js/src/main/scala/org/ergoplatform/sdk/js/Isos.scala @@ -1,36 +1,28 @@ package org.ergoplatform.sdk.js -import org.ergoplatform.ErgoBox._ import org.ergoplatform._ import org.ergoplatform.sdk.ExtendedInputBox -import org.ergoplatform.sdk.JavaHelpers.UniversalConverter import org.ergoplatform.sdk.wallet.protocol.context -import scorex.crypto.authds.ADKey -import scorex.util.ModifierId -import scorex.util.encode.Base16 -import sigma.Extensions.CollBytesOps -import sigma.ast.syntax.GroupElementConstant -import sigma.ast.{Constant, GroupElementConstant, SType} +import sigma.ast.{Constant, SType} +import sigma.data.Iso import sigma.data.Iso.{isoStringToArray, isoStringToColl} -import sigma.data.{CBigInt, CGroupElement, Digest32Coll, Digest32CollRType, Iso} +import sigma.data.js.{Isos => DataIsos} import sigma.interpreter.{ContextExtension, ProverResult} -import sigma.js.{AvlTree, GroupElement} -import sigma.serialization.{ErgoTreeSerializer, ValueSerializer} -import sigma.{Coll, Colls} +import sigma.js.AvlTree import sigmastate.eval.{CHeader, CPreHeader} import sigmastate.fleetSdkCommon.distEsmTypesBoxesMod.Box -import sigmastate.fleetSdkCommon.distEsmTypesCommonMod.HexString import sigmastate.fleetSdkCommon.distEsmTypesRegistersMod.NonMandatoryRegisters import sigmastate.fleetSdkCommon.distEsmTypesTokenMod.TokenAmount import sigmastate.fleetSdkCommon.distEsmTypesTransactionsMod.{SignedTransaction, UnsignedTransaction} -import sigmastate.fleetSdkCommon.{distEsmTypesBoxesMod => boxesMod, distEsmTypesCommonMod => commonMod, distEsmTypesContextExtensionMod => contextExtensionMod, distEsmTypesInputsMod => inputsMod, distEsmTypesProverResultMod => proverResultMod, distEsmTypesRegistersMod => registersMod, distEsmTypesTokenMod => tokenMod} -import sigma.data.js.{Isos => DataIsos} -import java.math.BigInteger +import sigmastate.fleetSdkCommon.{distEsmTypesCommonMod => commonMod, distEsmTypesContextExtensionMod => contextExtensionMod, distEsmTypesInputsMod => inputsMod, distEsmTypesProverResultMod => proverResultMod} + import scala.collection.immutable.ListMap import scala.scalajs.js import scala.scalajs.js.Object -/** Definitions of isomorphisms for sigma-sdk module. */ +/** Definitions of isomorphisms for sigma-sdk module. + * @see sigma.data.Iso + */ object Isos { implicit val isoHeader: Iso[Header, sigma.Header] = new Iso[Header, sigma.Header] { override def to(a: Header): sigma.Header = { From acecce014884395b58fb532d6a095372681f0ae4 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 3 May 2024 21:52:38 +0100 Subject: [PATCH 37/38] [sigma-js]: bump version 0.4.2 + update sigma-js/README.md --- sigma-js/README.md | 3 ++- sigma-js/package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sigma-js/README.md b/sigma-js/README.md index ff867e1cb6..c1f30f3497 100644 --- a/sigma-js/README.md +++ b/sigma-js/README.md @@ -46,14 +46,15 @@ with `$` suffix, thus if X is the JS class, then X$ is the JS object, which corr ## The list of modules and their exported classes - [sigma-core module](../core/js) - contains core classes of Sigma.js library - [Type](../core/js/src/main/scala/sigma/js/Type.scala) - - [Value](../core/js/src/main/scala/sigma/js/Value.scala) - [GroupElement](../core/js/src/main/scala/sigma/js/GroupElement.scala) - [SigmaProp](../core/js/src/main/scala/sigma/js/SigmaProp.scala) - [AvlTree](../core/js/src/main/scala/sigma/js/AvlTree.scala) - [sigma-data module](../data/js) - contains classes for working with ErgoTree, addresses and all related serializers - all classes from sigma-core module + - [Value](../data/js/src/main/scala/sigma/js/Value.scala) - [ErgoTree](../data/js/src/main/scala/sigma/ast/js/ErgoTree.scala) + - [Box](../data/js/src/main/scala/sigma/js/Box.scala) - [Address](../data/js/src/main/scala/org/ergoplatform/js/Address.scala) - [Expr](../data/js/src/main/scala/sigma/ast/js/Expr.scala) diff --git a/sigma-js/package.json b/sigma-js/package.json index 77ff920585..f6900571bd 100644 --- a/sigma-js/package.json +++ b/sigma-js/package.json @@ -1,6 +1,6 @@ { "name": "sigmastate-js", - "version": "0.4.0", + "version": "0.4.2", "description": "Sigma.js library", "files": [ "dist/", From d6efd22b61cda3e8ad6f1a14f619e813dddcb0f1 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 14 May 2024 15:40:16 +0100 Subject: [PATCH 38/38] v6.0.0-fix-tests: necessary changes due to MaxSupportedVersion upgrade --- .../src/test/scala/sigma/VersionTesting.scala | 4 +--- .../test/scala/sigma/SigmaDslSpecification.scala | 16 ++++++++-------- .../ScriptVersionSwitchSpecification.scala | 7 ++++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/core/shared/src/test/scala/sigma/VersionTesting.scala b/core/shared/src/test/scala/sigma/VersionTesting.scala index 69e15ff491..08053a6c48 100644 --- a/core/shared/src/test/scala/sigma/VersionTesting.scala +++ b/core/shared/src/test/scala/sigma/VersionTesting.scala @@ -39,9 +39,7 @@ 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/sc/shared/src/test/scala/sigma/SigmaDslSpecification.scala b/sc/shared/src/test/scala/sigma/SigmaDslSpecification.scala index 4dd576f03a..c820e65e73 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslSpecification.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslSpecification.scala @@ -5081,7 +5081,7 @@ class SigmaDslSpecification extends SigmaDslTesting newCost = 1766, newVersionedResults = { val res = (ExpectedResult(Success(0), Some(1766)) -> Some(selfCostDetails)) - Seq(0, 1, 2).map(version => version -> res) + Seq(0, 1, 2, 3).map(version => version -> res) })) ), changedFeature({ (x: Context) => x.selfBoxIndex }, @@ -5280,7 +5280,7 @@ class SigmaDslSpecification extends SigmaDslTesting Seq( ctx -> Expected(Failure(expectedError), 0, CostDetails.ZeroCost, 1793, newVersionedResults = { - Seq.tabulate(3)(v => v -> (ExpectedResult(Success(true), Some(1793)) -> None)) + Seq.tabulate(4)(v => v -> (ExpectedResult(Success(true), Some(1793)) -> None)) } ) ), @@ -6233,7 +6233,7 @@ class SigmaDslSpecification extends SigmaDslTesting cost = c, expectedDetails = CostDetails.ZeroCost, newCost = 1766, - newVersionedResults = Seq(0, 1, 2).map(i => i -> (ExpectedResult(Success(newV), Some(1766)) -> Some(cd))) + newVersionedResults = Seq(0, 1, 2, 3).map(i => i -> (ExpectedResult(Success(newV), Some(1766)) -> Some(cd))) ) Seq( (Coll[Boolean](), successNew(false, 1766, newV = false, costDetails(0))), @@ -6511,7 +6511,7 @@ class SigmaDslSpecification extends SigmaDslTesting newCost = 1769, newVersionedResults = { val res = (ExpectedResult(Success(Helpers.decodeBytes("00")), Some(1769)), Some(costDetails(1))) - Seq(0, 1, 2).map(version => version -> res) + Seq(0, 1, 2, 3).map(version => version -> res) } )), ((Helpers.decodeBytes("800136fe89afff802acea67128a0ff007fffe3498c8001806080012b"), @@ -9120,7 +9120,7 @@ class SigmaDslSpecification extends SigmaDslTesting cost = 0, expectedDetails = CostDetails.ZeroCost, newCost = 1766, - newVersionedResults = Seq.tabulate(3)(v => v -> (ExpectedResult(Success(5L), Some(1766)) -> Some(costDetails1))) + newVersionedResults = Seq.tabulate(4)(v => v -> (ExpectedResult(Success(5L), Some(1766)) -> Some(costDetails1))) )), (Some(0L) -> Expected( Success(1L), @@ -9679,7 +9679,7 @@ class SigmaDslSpecification extends SigmaDslTesting newCost = 1783, newVersionedResults = { val res = (ExpectedResult(Success(Helpers.decodeBytes("0008d3")), Some(1783)) -> Some(costDetails(0))) - Seq(0, 1, 2).map(version => version -> res) + Seq(0, 1, 2, 3).map(version => version -> res) }), (Helpers.decodeBytes("000008d3"), 0) -> Expected( @@ -9690,7 +9690,7 @@ class SigmaDslSpecification extends SigmaDslTesting newVersionedResults = { // since the tree without constant segregation, substitution has no effect val res = (ExpectedResult(Success(Helpers.decodeBytes("000008d3")), Some(1783)) -> Some(costDetails(0))) - Seq(0, 1, 2).map(version => version -> res) + Seq(0, 1, 2, 3).map(version => version -> res) }), // tree with segregation flag, empty constants array (Coll(t2.bytes:_*), 0) -> success(Helpers.decodeBytes("100008d3"), costDetails(0), 1783), @@ -9761,7 +9761,7 @@ class SigmaDslSpecification extends SigmaDslTesting cost = 1776, expectedDetails = CostDetails.ZeroCost, newCost = 1776, - newVersionedResults = (0 to 2).map(i => i -> (ExpectedResult(Success(true), Some(1776)) -> Some(costDetails))) + newVersionedResults = Seq(0, 1, 2, 3).map(i => i -> (ExpectedResult(Success(true), Some(1776)) -> Some(costDetails))) ) ), changedFeature( diff --git a/sc/shared/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sc/shared/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index b0206fa464..aedf35e914 100644 --- a/sc/shared/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -276,13 +276,14 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { * 20 | 4 | mined | Script v3 | v5.0 | skip-accept (rely on majority) */ property("Rules 19,20 | Block v4 | candidate or mined block | Script v3") { - forEachActivatedScriptVersion(activatedVers = Array[Byte](3)) // version for Block v4 + forEachActivatedScriptVersion(activatedVers = Array[Byte](4)) // activated version is greater then MaxSupported { - forEachErgoTreeVersion(ergoTreeVers = Array[Byte](3, 4)) { // scripts >= v3 + forEachErgoTreeVersion(ergoTreeVers = Array[Byte](4, 5)) { // tree version >= activated val headerFlags = ErgoTree.defaultHeaderWithVersion(ergoTreeVersionInTests) val ergoTree = createErgoTree(headerFlags) - // prover is rejecting, because such context parameters doesn't make sense + // prover is rejecting, because it cannot generate proofs for ErgoTrees with version + // higher than max supported by the interpreter assertExceptionThrown( testProve(ergoTree, activatedScriptVersion = activatedVersionInTests), exceptionLike[InterpreterException](s"Both ErgoTree version ${ergoTree.version} and activated version $activatedVersionInTests is greater than MaxSupportedScriptVersion $MaxSupportedScriptVersion")