From e22f12df8a7490156eb78b1c985a1693609d0a19 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 28 Oct 2019 15:30:56 +0300 Subject: [PATCH 01/16] SigmaBoolean.serializer, ErgoTreeSerializer.serializeHeader optimized --- .../scala/org/ergoplatform/ErgoAddress.scala | 2 +- .../src/main/scala/sigmastate/Values.scala | 28 ++++++++++----- .../sigmastate/eval/CostingDataContext.scala | 20 +++++++---- .../serialization/ErgoTreeSerializer.scala | 11 ++++-- .../GroupElementSerializer.scala | 2 +- .../src/main/scala/sigmastate/trees.scala | 35 ++++++++++++------- 6 files changed, 66 insertions(+), 32 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala index d992f382e0..35b14e3036 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoAddress.scala @@ -84,7 +84,7 @@ class P2PKAddress(val pubkey: ProveDlog, override val script: ErgoTree = { // NOTE: we don't segregate constants because the whole tree is single constant // and we want different addreses of this type to have different `script` values - ErgoTree(ErgoTree.DefaultHeader, IndexedSeq.empty, SigmaPropConstant(pubkey)) + ErgoTree(ErgoTree.DefaultHeader, ErgoTree.EmptyConstants, SigmaPropConstant(pubkey)) } override def equals(obj: Any): Boolean = obj match { diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index 91b5eed9cd..2c31c8fa04 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -550,6 +550,8 @@ object Values { object SigmaBoolean { val PropBytes = "propBytes" val IsValid = "isValid" + + /** @hotspot don't beautify this code */ object serializer extends SigmaSerializer[SigmaBoolean, SigmaBoolean] { val dhtSerializer = ProveDHTupleSerializer(ProveDHTuple.apply) val dlogSerializer = ProveDlogSerializer(ProveDlog.apply) @@ -561,22 +563,32 @@ object Values { case dht: ProveDHTuple => dhtSerializer.serialize(dht, w) case _: TrivialProp => // besides opCode no additional bytes case and: CAND => - w.putUShort(and.sigmaBooleans.length) - for (c <- and.sigmaBooleans) + val nChildren = and.sigmaBooleans.length + w.putUShort(nChildren) + cfor(0)(_ < nChildren, _ + 1) { i => + val c = and.sigmaBooleans(i) serializer.serialize(c, w) + } + case or: COR => - w.putUShort(or.sigmaBooleans.length) - for (c <- or.sigmaBooleans) + val nChildren = or.sigmaBooleans.length + w.putUShort(nChildren) + cfor(0)(_ < nChildren, _ + 1) { i => + val c = or.sigmaBooleans(i) serializer.serialize(c, w) + } + case th: CTHRESHOLD => w.putUShort(th.k) - w.putUShort(th.sigmaBooleans.length) - for (c <- th.sigmaBooleans) + val nChildren = th.sigmaBooleans.length + w.putUShort(nChildren) + cfor(0)(_ < nChildren, _ + 1) { i => + val c = th.sigmaBooleans(i) serializer.serialize(c, w) + } } } - /** @hotspot don't beautify this code */ override def parse(r: SigmaByteReader): SigmaBoolean = { val depth = r.level r.level = depth + 1 @@ -1001,7 +1013,7 @@ object Values { new ErgoTree(header, constants, Right(root)) } - val EmptyConstants: IndexedSeq[Constant[SType]] = IndexedSeq.empty[Constant[SType]] + val EmptyConstants: IndexedSeq[Constant[SType]] = Array[Constant[SType]]() def withoutSegregation(root: SigmaPropValue): ErgoTree = ErgoTree(ErgoTree.DefaultHeader, EmptyConstants, root) diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index 50988e76dd..5b34e3eda4 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -63,19 +63,19 @@ case class CSigmaProp(sigmaTree: SigmaBoolean) extends SigmaProp with WrapperOf[ override def &&(other: SigmaProp): SigmaProp = other match { case other: CSigmaProp => - CSigmaProp(CAND.normalized(Seq(sigmaTree, other.sigmaTree))) + CSigmaProp(CAND.normalized(Array(sigmaTree, other.sigmaTree))) } override def &&(other: Boolean): SigmaProp = - CSigmaProp(CAND.normalized(Seq(sigmaTree, TrivialProp(other)))) + CSigmaProp(CAND.normalized(Array(sigmaTree, TrivialProp(other)))) override def ||(other: SigmaProp): SigmaProp = other match { case other: CSigmaProp => - CSigmaProp(COR.normalized(Seq(sigmaTree, other.sigmaTree))) + CSigmaProp(COR.normalized(Array(sigmaTree, other.sigmaTree))) } override def ||(other: Boolean): SigmaProp = - CSigmaProp(COR.normalized(Seq(sigmaTree, TrivialProp(other)))) + CSigmaProp(COR.normalized(Array(sigmaTree, TrivialProp(other)))) override def toString: String = s"SigmaProp(${wrappedValue.showToString})" } @@ -529,11 +529,17 @@ class CostingSigmaDslBuilder extends TestSigmaDslBuilder { dsl => def Box(ebox: ErgoBox): Box = CostingBox(false, ebox) def toErgoBox(b: Box): ErgoBox = b.asInstanceOf[CostingBox].ebox + /** @hotspot don't beautify this code */ private def toSigmaTrees(props: Array[SigmaProp]): Array[SigmaBoolean] = { - props.map { - case csp: CSigmaProp => csp.sigmaTree - case m: MockSigma => TrivialProp(m.isValid) //needed for tests, e.g. "atLeast" test + val len = props.length + val res = new Array[SigmaBoolean](len) + cfor(0)(_ < len, _ + 1) { i => + res(i) = props(i) match { + case csp: CSigmaProp => csp.sigmaTree + case m: MockSigma => TrivialProp(m.isValid) //needed for tests, e.g. "atLeast" test + } } + res } @inline private def toEcPointType(ge: GroupElement): EcPointType = diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala index 2adb516431..e809854b78 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala @@ -84,8 +84,13 @@ class ErgoTreeSerializer { w.put(ergoTree.header) if (ergoTree.isConstantSegregation) { val constantSerializer = ConstantSerializer(DeserializationSigmaBuilder) - w.putUInt(ergoTree.constants.length) - ergoTree.constants.foreach(c => constantSerializer.serialize(c, w)) + val constants = ergoTree.constants + val nConstants = constants.length + w.putUInt(nConstants) + cfor(0)(_ < nConstants, _ + 1) { i => + val c = constants(i) + constantSerializer.serialize(c, w) + } } } @@ -102,7 +107,7 @@ class ErgoTreeSerializer { * structure after deserialization. */ def serializeErgoTree(ergoTree: ErgoTree): Array[Byte] = { val res = ergoTree.root match { - case Left(UnparsedErgoTree(bytes, error)) => bytes.array + case Left(UnparsedErgoTree(bytes, _)) => bytes.array case _ => val bytes = serializeWithoutSize(ergoTree) if (ergoTree.hasSize) { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala index 4305e899c5..4998ab94d7 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/GroupElementSerializer.scala @@ -36,7 +36,7 @@ object GroupElementSerializer extends SigmaSerializer[EcPointType, EcPointType] override def parse(r: SigmaByteReader): EcPointType = { val encoded = r.getBytes(encodingSize) - if (encoded.head != 0) { + if (encoded(0) != 0) { curve.curve.decodePoint(encoded).asInstanceOf[EcPointType] } else { curve.identity diff --git a/sigmastate/src/main/scala/sigmastate/trees.scala b/sigmastate/src/main/scala/sigmastate/trees.scala index 758d0a5010..762aae3654 100644 --- a/sigmastate/src/main/scala/sigmastate/trees.scala +++ b/sigmastate/src/main/scala/sigmastate/trees.scala @@ -276,16 +276,19 @@ object AtLeast extends ValueCompanion { def apply(bound: Value[SInt.type], head: SigmaPropValue, tail: SigmaPropValue*): AtLeast = apply(bound, head +: tail) + /** @hotspot don't beautify this code */ def reduce(bound: Int, children: Seq[SigmaBoolean]): SigmaBoolean = { import sigmastate.TrivialProp._ if (bound <= 0) return TrueProp - if (bound > children.length) return FalseProp + val nChildren = children.length + if (bound > nChildren) return FalseProp var curBound = bound - var childrenLeft = children.length + var childrenLeft = nChildren // invariant due to the two if statements above: 0=255) return FalseLeaf - for (iChild <- children.indices) { - if (curBound == 1) - return COR.normalized(sigmas ++ children.slice(iChild, children.length)) + var iChild = 0 + while (iChild < nChildren) { + if (curBound == 1) { + sigmas ++= children.slice(iChild, nChildren) + return COR.normalized(sigmas.result()) + } // If at any point bound == number of children, convert to AND. - if (curBound == childrenLeft) - return CAND.normalized(sigmas ++ children.slice(iChild, children.length)) + if (curBound == childrenLeft) { + sigmas ++= children.slice(iChild, nChildren) + return CAND.normalized(sigmas.result()) + } // at this point 1 // If child is true, remove child and reduce bound. @@ -312,10 +320,13 @@ object AtLeast extends ValueCompanion { case sigma => sigmas += sigma } // at this point 1<=curBound<=childrenLeft + iChild += 1 } - if (curBound == 1) return COR.normalized(sigmas) - if (curBound == childrenLeft) return CAND.normalized(sigmas) - CTHRESHOLD(curBound, sigmas) + + val ch = sigmas.result() + if (curBound == 1) return COR.normalized(ch) + if (curBound == childrenLeft) return CAND.normalized(ch) + CTHRESHOLD(curBound, ch) } } From aeadc8176e629c3c808ae3190b9fe888c2e5d005 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 28 Oct 2019 16:17:37 +0300 Subject: [PATCH 02/16] replace Seq with Array in Operations.scala --- .../main/scala/sigmastate/Operations.scala | 152 +++++++++--------- .../sigmastate/utils/GenInfoObjects.scala | 4 +- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/Operations.scala b/sigmastate/src/main/scala/sigmastate/Operations.scala index 34931e3df0..51ae277757 100644 --- a/sigmastate/src/main/scala/sigmastate/Operations.scala +++ b/sigmastate/src/main/scala/sigmastate/Operations.scala @@ -16,103 +16,103 @@ object Operations { object ANDInfo extends InfoObject { private val func = predefinedOps.funcs("allOf") val conditionsArg: ArgInfo = func.argInfo("conditions") - val argInfos: Seq[ArgInfo] = Seq(conditionsArg) + val argInfos: Seq[ArgInfo] = Array(conditionsArg) } object AppendInfo extends InfoObject { private val method = SMethod.fromIds(12, 9) val thisArg: ArgInfo = method.argInfo("this") val otherArg: ArgInfo = method.argInfo("other") - val argInfos: Seq[ArgInfo] = Seq(thisArg, otherArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, otherArg) } object ApplyInfo extends InfoObject { private val func = predefinedOps.specialFuncs("apply") val funcArg: ArgInfo = func.argInfo("func") val argsArg: ArgInfo = func.argInfo("args") - val argInfos: Seq[ArgInfo] = Seq(funcArg, argsArg) + val argInfos: Seq[ArgInfo] = Array(funcArg, argsArg) } object AtLeastInfo extends InfoObject { private val func = predefinedOps.funcs("atLeast") val boundArg: ArgInfo = func.argInfo("bound") val childrenArg: ArgInfo = func.argInfo("children") - val argInfos: Seq[ArgInfo] = Seq(boundArg, childrenArg) + val argInfos: Seq[ArgInfo] = Array(boundArg, childrenArg) } object BinAndInfo extends InfoObject { private val func = predefinedOps.funcs("&&") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object BinOrInfo extends InfoObject { private val func = predefinedOps.funcs("||") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object BinXorInfo extends InfoObject { private val func = predefinedOps.funcs("^") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object BitAndInfo extends InfoObject { private val func = predefinedOps.funcs("bit_&") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object BitInversionInfo extends InfoObject { private val func = predefinedOps.funcs("unary_~") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object BitOrInfo extends InfoObject { private val func = predefinedOps.funcs("bit_|") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object BitShiftLeftInfo extends InfoObject { private val func = predefinedOps.funcs("bit_<<") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object BitShiftRightInfo extends InfoObject { private val func = predefinedOps.funcs("bit_>>") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object BitShiftRightZeroedInfo extends InfoObject { private val func = predefinedOps.funcs("bit_>>>") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object BitXorInfo extends InfoObject { private val func = predefinedOps.funcs("bit_^") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object BoolToSigmaPropInfo extends InfoObject { private val func = predefinedOps.funcs("sigmaProp") val conditionArg: ArgInfo = func.argInfo("condition") - val argInfos: Seq[ArgInfo] = Seq(conditionArg) + val argInfos: Seq[ArgInfo] = Array(conditionArg) } object ByIndexInfo extends InfoObject { @@ -120,37 +120,37 @@ object Operations { val thisArg: ArgInfo = method.argInfo("this") val indexArg: ArgInfo = method.argInfo("index") val defaultArg: ArgInfo = method.argInfo("default") - val argInfos: Seq[ArgInfo] = Seq(thisArg, indexArg, defaultArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, indexArg, defaultArg) } object ByteArrayToBigIntInfo extends InfoObject { private val func = predefinedOps.funcs("byteArrayToBigInt") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object ByteArrayToLongInfo extends InfoObject { private val func = predefinedOps.funcs("byteArrayToLong") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object CalcBlake2b256Info extends InfoObject { private val func = predefinedOps.funcs("blake2b256") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object CalcSha256Info extends InfoObject { private val func = predefinedOps.funcs("sha256") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object ConstantPlaceholderInfo extends InfoObject { private val func = predefinedOps.specialFuncs("placeholder") val indexArg: ArgInfo = func.argInfo("index") - val argInfos: Seq[ArgInfo] = Seq(indexArg) + val argInfos: Seq[ArgInfo] = Array(indexArg) } object CreateAvlTreeInfo extends InfoObject { @@ -159,7 +159,7 @@ object Operations { val digestArg: ArgInfo = func.argInfo("digest") val keyLengthArg: ArgInfo = func.argInfo("keyLength") val valueLengthOptArg: ArgInfo = func.argInfo("valueLengthOpt") - val argInfos: Seq[ArgInfo] = Seq(operationFlagsArg, digestArg, keyLengthArg, valueLengthOptArg) + val argInfos: Seq[ArgInfo] = Array(operationFlagsArg, digestArg, keyLengthArg, valueLengthOptArg) } object CreateProveDHTupleInfo extends InfoObject { @@ -168,116 +168,116 @@ object Operations { val hArg: ArgInfo = func.argInfo("h") val uArg: ArgInfo = func.argInfo("u") val vArg: ArgInfo = func.argInfo("v") - val argInfos: Seq[ArgInfo] = Seq(gArg, hArg, uArg, vArg) + val argInfos: Seq[ArgInfo] = Array(gArg, hArg, uArg, vArg) } object CreateProveDlogInfo extends InfoObject { private val func = predefinedOps.funcs("proveDlog") val valueArg: ArgInfo = func.argInfo("value") - val argInfos: Seq[ArgInfo] = Seq(valueArg) + val argInfos: Seq[ArgInfo] = Array(valueArg) } object DecodePointInfo extends InfoObject { private val func = predefinedOps.funcs("decodePoint") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object DeserializeContextInfo extends InfoObject { private val func = predefinedOps.funcs("executeFromVar") val idArg: ArgInfo = func.argInfo("id") - val argInfos: Seq[ArgInfo] = Seq(idArg) + val argInfos: Seq[ArgInfo] = Array(idArg) } object DeserializeRegisterInfo extends InfoObject { private val func = predefinedOps.funcs("executeFromSelfReg") val idArg: ArgInfo = func.argInfo("id") val defaultArg: ArgInfo = func.argInfo("default") - val argInfos: Seq[ArgInfo] = Seq(idArg, defaultArg) + val argInfos: Seq[ArgInfo] = Array(idArg, defaultArg) } object DivisionInfo extends InfoObject { private val func = predefinedOps.funcs("/") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object DowncastInfo extends InfoObject { private val func = predefinedOps.specialFuncs("downcast") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object EQInfo extends InfoObject { private val func = predefinedOps.funcs("==") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object ExistsInfo extends InfoObject { private val method = SMethod.fromIds(12, 4) val thisArg: ArgInfo = method.argInfo("this") val pArg: ArgInfo = method.argInfo("p") - val argInfos: Seq[ArgInfo] = Seq(thisArg, pArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, pArg) } object ExponentiateInfo extends InfoObject { private val method = SMethod.fromIds(7, 3) val thisArg: ArgInfo = method.argInfo("this") val kArg: ArgInfo = method.argInfo("k") - val argInfos: Seq[ArgInfo] = Seq(thisArg, kArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, kArg) } object ExtractAmountInfo extends InfoObject { private val method = SMethod.fromIds(99, 1) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object ExtractBytesInfo extends InfoObject { private val method = SMethod.fromIds(99, 3) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object ExtractBytesWithNoRefInfo extends InfoObject { private val method = SMethod.fromIds(99, 4) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object ExtractCreationInfoInfo extends InfoObject { private val method = SMethod.fromIds(99, 6) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object ExtractIdInfo extends InfoObject { private val method = SMethod.fromIds(99, 5) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object ExtractRegisterAsInfo extends InfoObject { private val method = SMethod.fromIds(99, 7) val thisArg: ArgInfo = method.argInfo("this") val regIdArg: ArgInfo = method.argInfo("regId") - val argInfos: Seq[ArgInfo] = Seq(thisArg, regIdArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, regIdArg) } object ExtractScriptBytesInfo extends InfoObject { private val method = SMethod.fromIds(99, 2) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object FilterInfo extends InfoObject { private val method = SMethod.fromIds(12, 8) val thisArg: ArgInfo = method.argInfo("this") val pArg: ArgInfo = method.argInfo("p") - val argInfos: Seq[ArgInfo] = Seq(thisArg, pArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, pArg) } object FoldInfo extends InfoObject { @@ -285,40 +285,40 @@ object Operations { val thisArg: ArgInfo = method.argInfo("this") val zeroArg: ArgInfo = method.argInfo("zero") val opArg: ArgInfo = method.argInfo("op") - val argInfos: Seq[ArgInfo] = Seq(thisArg, zeroArg, opArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, zeroArg, opArg) } object ForAllInfo extends InfoObject { private val method = SMethod.fromIds(12, 6) val thisArg: ArgInfo = method.argInfo("this") val pArg: ArgInfo = method.argInfo("p") - val argInfos: Seq[ArgInfo] = Seq(thisArg, pArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, pArg) } object GEInfo extends InfoObject { private val func = predefinedOps.funcs(">=") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object GTInfo extends InfoObject { private val func = predefinedOps.funcs(">") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object GetVarInfo extends InfoObject { private val func = predefinedOps.funcs("getVar") val varIdArg: ArgInfo = func.argInfo("varId") - val argInfos: Seq[ArgInfo] = Seq(varIdArg) + val argInfos: Seq[ArgInfo] = Array(varIdArg) } object GroupGeneratorInfo extends InfoObject { private val method = SMethod.fromIds(106, 1) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object IfInfo extends InfoObject { @@ -326,158 +326,158 @@ object Operations { val conditionArg: ArgInfo = func.argInfo("condition") val trueBranchArg: ArgInfo = func.argInfo("trueBranch") val falseBranchArg: ArgInfo = func.argInfo("falseBranch") - val argInfos: Seq[ArgInfo] = Seq(conditionArg, trueBranchArg, falseBranchArg) + val argInfos: Seq[ArgInfo] = Array(conditionArg, trueBranchArg, falseBranchArg) } object LEInfo extends InfoObject { private val func = predefinedOps.funcs("<=") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object LTInfo extends InfoObject { private val func = predefinedOps.funcs("<") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object LogicalNotInfo extends InfoObject { private val func = predefinedOps.funcs("unary_!") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object LongToByteArrayInfo extends InfoObject { private val func = predefinedOps.funcs("longToByteArray") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object MapCollectionInfo extends InfoObject { private val method = SMethod.fromIds(12, 3) val thisArg: ArgInfo = method.argInfo("this") val fArg: ArgInfo = method.argInfo("f") - val argInfos: Seq[ArgInfo] = Seq(thisArg, fArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, fArg) } object MaxInfo extends InfoObject { private val func = predefinedOps.funcs("max") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object MinInfo extends InfoObject { private val func = predefinedOps.funcs("min") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object MinusInfo extends InfoObject { private val func = predefinedOps.funcs("-") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object ModuloInfo extends InfoObject { private val func = predefinedOps.funcs("%") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object MultiplyInfo extends InfoObject { private val func = predefinedOps.funcs("*") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object MultiplyGroupInfo extends InfoObject { private val method = SMethod.fromIds(7, 4) val thisArg: ArgInfo = method.argInfo("this") val otherArg: ArgInfo = method.argInfo("other") - val argInfos: Seq[ArgInfo] = Seq(thisArg, otherArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, otherArg) } object NEQInfo extends InfoObject { private val func = predefinedOps.funcs("!=") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object NegationInfo extends InfoObject { private val func = predefinedOps.funcs("unary_-") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object ORInfo extends InfoObject { private val func = predefinedOps.funcs("anyOf") val conditionsArg: ArgInfo = func.argInfo("conditions") - val argInfos: Seq[ArgInfo] = Seq(conditionsArg) + val argInfos: Seq[ArgInfo] = Array(conditionsArg) } object OptionGetInfo extends InfoObject { private val method = SMethod.fromIds(36, 3) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object OptionGetOrElseInfo extends InfoObject { private val method = SMethod.fromIds(36, 4) val thisArg: ArgInfo = method.argInfo("this") val defaultArg: ArgInfo = method.argInfo("default") - val argInfos: Seq[ArgInfo] = Seq(thisArg, defaultArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, defaultArg) } object OptionIsDefinedInfo extends InfoObject { private val method = SMethod.fromIds(36, 2) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object PlusInfo extends InfoObject { private val func = predefinedOps.funcs("+") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object SelectFieldInfo extends InfoObject { private val func = predefinedOps.specialFuncs("selectField") val inputArg: ArgInfo = func.argInfo("input") val fieldIndexArg: ArgInfo = func.argInfo("fieldIndex") - val argInfos: Seq[ArgInfo] = Seq(inputArg, fieldIndexArg) + val argInfos: Seq[ArgInfo] = Array(inputArg, fieldIndexArg) } object SigmaAndInfo extends InfoObject { private val func = predefinedOps.funcs("allZK") val propositionsArg: ArgInfo = func.argInfo("propositions") - val argInfos: Seq[ArgInfo] = Seq(propositionsArg) + val argInfos: Seq[ArgInfo] = Array(propositionsArg) } object SigmaOrInfo extends InfoObject { private val func = predefinedOps.funcs("anyZK") val propositionsArg: ArgInfo = func.argInfo("propositions") - val argInfos: Seq[ArgInfo] = Seq(propositionsArg) + val argInfos: Seq[ArgInfo] = Array(propositionsArg) } object SigmaPropBytesInfo extends InfoObject { private val method = SMethod.fromIds(8, 1) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object SizeOfInfo extends InfoObject { private val method = SMethod.fromIds(12, 1) val thisArg: ArgInfo = method.argInfo("this") - val argInfos: Seq[ArgInfo] = Seq(thisArg) + val argInfos: Seq[ArgInfo] = Array(thisArg) } object SliceInfo extends InfoObject { @@ -485,7 +485,7 @@ object Operations { val thisArg: ArgInfo = method.argInfo("this") val fromArg: ArgInfo = method.argInfo("from") val untilArg: ArgInfo = method.argInfo("until") - val argInfos: Seq[ArgInfo] = Seq(thisArg, fromArg, untilArg) + val argInfos: Seq[ArgInfo] = Array(thisArg, fromArg, untilArg) } object SubstConstantsInfo extends InfoObject { @@ -493,7 +493,7 @@ object Operations { val scriptBytesArg: ArgInfo = func.argInfo("scriptBytes") val positionsArg: ArgInfo = func.argInfo("positions") val newValuesArg: ArgInfo = func.argInfo("newValues") - val argInfos: Seq[ArgInfo] = Seq(scriptBytesArg, positionsArg, newValuesArg) + val argInfos: Seq[ArgInfo] = Array(scriptBytesArg, positionsArg, newValuesArg) } object TreeLookupInfo extends InfoObject { @@ -501,26 +501,26 @@ object Operations { val treeArg: ArgInfo = func.argInfo("tree") val keyArg: ArgInfo = func.argInfo("key") val proofArg: ArgInfo = func.argInfo("proof") - val argInfos: Seq[ArgInfo] = Seq(treeArg, keyArg, proofArg) + val argInfos: Seq[ArgInfo] = Array(treeArg, keyArg, proofArg) } object UpcastInfo extends InfoObject { private val func = predefinedOps.specialFuncs("upcast") val inputArg: ArgInfo = func.argInfo("input") - val argInfos: Seq[ArgInfo] = Seq(inputArg) + val argInfos: Seq[ArgInfo] = Array(inputArg) } object XorInfo extends InfoObject { private val func = predefinedOps.funcs("binary_|") val leftArg: ArgInfo = func.argInfo("left") val rightArg: ArgInfo = func.argInfo("right") - val argInfos: Seq[ArgInfo] = Seq(leftArg, rightArg) + val argInfos: Seq[ArgInfo] = Array(leftArg, rightArg) } object XorOfInfo extends InfoObject { private val func = predefinedOps.funcs("xorOf") val conditionsArg: ArgInfo = func.argInfo("conditions") - val argInfos: Seq[ArgInfo] = Seq(conditionsArg) + val argInfos: Seq[ArgInfo] = Array(conditionsArg) } } diff --git a/sigmastate/src/test/scala/sigmastate/utils/GenInfoObjects.scala b/sigmastate/src/test/scala/sigmastate/utils/GenInfoObjects.scala index a6169dc4cf..c17aa7cb72 100644 --- a/sigmastate/src/test/scala/sigmastate/utils/GenInfoObjects.scala +++ b/sigmastate/src/test/scala/sigmastate/utils/GenInfoObjects.scala @@ -43,7 +43,7 @@ object GenInfoObjects extends SpecGen { | object ${opName}Info extends InfoObject { | private val method = SMethod.fromIds(${typeId}, ${m.methodId}) | ${args.rep(sep = "\n ")} - | val argInfos: Seq[ArgInfo] = Seq(${info.args.rep(a => s"${a.name}Arg")}) + | val argInfos: Seq[ArgInfo] = Array(${info.args.rep(a => s"${a.name}Arg")}) | } """.stripMargin case Left(f) => @@ -59,7 +59,7 @@ object GenInfoObjects extends SpecGen { | object ${opName}Info extends InfoObject { | private val func = predefinedOps.${ if (isSpecialFunc) "specialFuncs" else "funcs" }("${f.name}") | ${args.rep(sep = "\n ")} - | val argInfos: Seq[ArgInfo] = Seq(${info.args.rep(a => s"${a.name}Arg")}) + | val argInfos: Seq[ArgInfo] = Array(${info.args.rep(a => s"${a.name}Arg")}) | } """.stripMargin } From 4be33dae9ad254fd066f9698318d7430ba3e4f3e Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 28 Oct 2019 17:24:24 +0300 Subject: [PATCH 03/16] optimized ConcreteCollectionSerializer --- .../ConcreteCollectionSerializer.scala | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala index 5449e717f4..7c1596a760 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala @@ -1,19 +1,24 @@ package sigmastate.serialization -import sigmastate.{SCollection, SType, ArgInfo} +import sigmastate.{SCollection, ArgInfo, SType} import sigmastate.Values._ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import ValueSerializer._ +import sigmastate.utils.SigmaByteWriter.{U, Vlq, DataInfo} import spire.syntax.all.cfor case class ConcreteCollectionSerializer(cons: (IndexedSeq[Value[SType]], SType) => Value[SCollection[SType]]) extends ValueSerializer[ConcreteCollection[_ <: SType]] { - override def opDesc = ConcreteCollection + override val opDesc = ConcreteCollection + + val numItemsInfo: DataInfo[Vlq[U[Short]]] = ArgInfo("numItems", "number of item in a collection of expressions") + val elementTypeInfo: DataInfo[SType] = ArgInfo("elementType", "type of each expression in the collection") + val itemInfo: DataInfo[SValue] = ArgInfo("item_i", "expression in i-th position") override def serialize(cc: ConcreteCollection[_ <: SType], w: SigmaByteWriter): Unit = { - w.putUShort(cc.items.size, ArgInfo("numItems", "number of item in a collection of expressions")) - w.putType(cc.tpe.elemType, ArgInfo("elementType", "type of each expression in the collection")) - foreach("numItems", cc.items)(w.putValue(_, ArgInfo("item_i", "expression in i-th position"))) + w.putUShort(cc.items.size, numItemsInfo) + w.putType(cc.tpe.elemType, elementTypeInfo) + foreach("numItems", cc.items)(w.putValue(_, itemInfo)) } /** @hotspot don't beautify this code */ From 0884c9f5e195b20fa564f83864a936f2977e5fe0 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 28 Oct 2019 17:24:49 +0300 Subject: [PATCH 04/16] optimized serializeBodyWithIndexedDigests --- .../scala/org/ergoplatform/ErgoBoxCandidate.scala | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala index 332c2ac533..12c332b40c 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoBoxCandidate.scala @@ -81,6 +81,8 @@ class ErgoBoxCandidate(val value: Long, object ErgoBoxCandidate { val UndefinedBoxRef: Coll[Byte] = Array.fill(34)(0: Byte).toColl + + /** @hotspot don't beautify the code */ object serializer extends SigmaSerializer[ErgoBoxCandidate, ErgoBoxCandidate] { def serializeBodyWithIndexedDigests(obj: ErgoBoxCandidate, @@ -90,7 +92,14 @@ object ErgoBoxCandidate { w.putBytes(DefaultSerializer.serializeErgoTree(obj.ergoTree)) w.putUInt(obj.creationHeight) w.putUByte(obj.additionalTokens.size) - obj.additionalTokens.foreach { case (id, amount) => + + val unzipped = Colls.unzip(obj.additionalTokens) + val ids = unzipped._1 + val amounts = unzipped._2 + val limit = ids.length + cfor(0)(_ < limit, _ + 1) { i => + val id = ids(i) + val amount = amounts(i) if (tokensInTx.isDefined) { val tokenIndex = tokensInTx.get.indexWhere(v => util.Arrays.equals(v, id), 0) if (tokenIndex == -1) sys.error(s"failed to find token id ($id) in tx's digest index") @@ -100,6 +109,7 @@ object ErgoBoxCandidate { } w.putULong(amount) } + val nRegs = obj.additionalRegisters.keys.size if (nRegs + ErgoBox.startingNonMandatoryIndex > 255) sys.error(s"The number of non-mandatory indexes $nRegs exceeds ${255 - ErgoBox.startingNonMandatoryIndex} limit.") @@ -108,7 +118,7 @@ object ErgoBoxCandidate { // this convention allows to save 1 bite for each register val startReg = ErgoBox.startingNonMandatoryIndex val endReg = ErgoBox.startingNonMandatoryIndex + nRegs - 1 - for (regId <- startReg to endReg) { + cfor(startReg: Int)(_ <= endReg, _ + 1) { regId => val reg = ErgoBox.findRegisterByIndex(regId.toByte).get obj.get(reg) match { case Some(v) => @@ -124,7 +134,6 @@ object ErgoBoxCandidate { serializeBodyWithIndexedDigests(obj, None, w) } - /** @hotspot don't beautify the code */ def parseBodyWithIndexedDigests(digestsInTx: Option[Coll[TokenId]], r: SigmaByteReader): ErgoBoxCandidate = { val previousPositionLimit = r.positionLimit r.positionLimit = r.position + ErgoBox.MaxBoxSize From d491d36e1cbe5194b85323b6ab79f1d8c02e2ee8 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Mon, 28 Oct 2019 23:59:38 +0300 Subject: [PATCH 05/16] ConcreteCollection don't use IndexedSeq --- .../src/main/scala/sigmastate/Values.scala | 10 +-- .../scala/sigmastate/lang/SigmaBuilder.scala | 4 +- .../scala/sigmastate/lang/SigmaTyper.scala | 2 +- .../src/main/scala/sigmastate/trees.scala | 8 +-- .../scala/sigmastate/utxo/transformers.scala | 2 +- .../scala/sigmastate/lang/LangTests.scala | 4 +- .../sigmastate/lang/SigmaBinderTest.scala | 10 +-- .../sigmastate/lang/SigmaCompilerTest.scala | 66 +++++++++---------- .../lang/SigmaSpecializerTest.scala | 4 +- ...eteCollectionSerializerSpecification.scala | 6 +- .../ConcreteCollectionGenerators.scala | 6 +- .../utxo/AVLTreeScriptsSpecification.scala | 2 +- .../utxo/BasicOpsSpecification.scala | 8 +-- .../CollectionOperationsSpecification.scala | 6 +- .../examples/FsmExampleSpecification.scala | 2 +- 15 files changed, 70 insertions(+), 70 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index 2c31c8fa04..368cd68f8d 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -667,7 +667,7 @@ object Values { override val opCode = NoneValueCode } - case class ConcreteCollection[V <: SType](items: IndexedSeq[Value[V]], elementType: V) + case class ConcreteCollection[V <: SType](items: Seq[Value[V]], elementType: V) extends EvaluatedCollection[V, SCollection[V]] { private val isBooleanConstants = elementType == SBoolean && items.forall(_.isInstanceOf[Constant[_]]) override def companion = @@ -684,11 +684,11 @@ object Values { } object ConcreteCollection extends ValueCompanion { override def opCode: OpCode = ConcreteCollectionCode - def apply[V <: SType](items: Value[V]*)(implicit tV: V): ConcreteCollection[V] = - ConcreteCollection(items.toIndexedSeq, tV) + def fromSeq[V <: SType](items: Seq[Value[V]])(implicit tV: V): ConcreteCollection[V] = + ConcreteCollection(items, tV) - def apply[V <: SType](items: => Seq[Value[V]])(implicit tV: V): ConcreteCollection[V] = - ConcreteCollection(items.toIndexedSeq, tV) + def fromItems[V <: SType](items: Value[V]*)(implicit tV: V): ConcreteCollection[V] = + ConcreteCollection(items, tV) } object ConcreteCollectionBooleanConstant extends ValueCompanion { override def opCode: OpCode = ConcreteCollectionBooleanConstantCode diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaBuilder.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaBuilder.scala index ca7186a980..5849fa1ffc 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/SigmaBuilder.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaBuilder.scala @@ -151,7 +151,7 @@ trait SigmaBuilder { def mkSigmaAnd(items: Seq[SigmaPropValue]): SigmaPropValue def mkSigmaOr(items: Seq[SigmaPropValue]): SigmaPropValue - def mkConcreteCollection[T <: SType](items: IndexedSeq[Value[T]], + def mkConcreteCollection[T <: SType](items: Seq[Value[T]], elementType: T): Value[SCollection[T]] def mkTaggedVariable[T <: SType](varId: Byte, tpe: T): TaggedVariable[T] @@ -504,7 +504,7 @@ class StdSigmaBuilder extends SigmaBuilder { override def mkSigmaOr(items: Seq[SigmaPropValue]): SigmaPropValue = SigmaOr(items).withSrcCtx(currentSrcCtx.value) - override def mkConcreteCollection[T <: SType](items: IndexedSeq[Value[T]], + override def mkConcreteCollection[T <: SType](items: Seq[Value[T]], elementType: T): Value[SCollection[T]] = ConcreteCollection(items, elementType).withSrcCtx(currentSrcCtx.value) diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala index 0de4fd40f2..58906d08a4 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala @@ -510,7 +510,7 @@ class SigmaTyper(val builder: SigmaBuilder, predefFuncRegistry: PredefinedFuncRe error(s"Don't know how to assignType($v)", v.sourceContext) }).withEnsuredSrcCtx(bound.sourceContext) - def assignConcreteCollection(cc: ConcreteCollection[SType], newItems: IndexedSeq[Value[SType]]) = { + def assignConcreteCollection(cc: ConcreteCollection[SType], newItems: Seq[Value[SType]]) = { val types = newItems.map(_.tpe).distinct val tItem = if (cc.items.isEmpty) { if (cc.elementType == NoType) diff --git a/sigmastate/src/main/scala/sigmastate/trees.scala b/sigmastate/src/main/scala/sigmastate/trees.scala index 762aae3654..a6b4fa0710 100644 --- a/sigmastate/src/main/scala/sigmastate/trees.scala +++ b/sigmastate/src/main/scala/sigmastate/trees.scala @@ -206,7 +206,7 @@ object OR extends LogicalTransformerCompanion { override def argInfos: Seq[ArgInfo] = Operations.ORInfo.argInfos def apply(children: Seq[Value[SBoolean.type]]): OR = - OR(ConcreteCollection(children.toIndexedSeq)) + OR(ConcreteCollection.fromSeq(children)) def apply(head: Value[SBoolean.type], tail: Value[SBoolean.type]*): OR = apply(head +: tail) } @@ -224,7 +224,7 @@ object XorOf extends LogicalTransformerCompanion { override def argInfos: Seq[ArgInfo] = Operations.XorOfInfo.argInfos def apply(children: Seq[Value[SBoolean.type]]): XorOf = - XorOf(ConcreteCollection(children.toIndexedSeq)) + XorOf(ConcreteCollection.fromSeq(children)) def apply(head: Value[SBoolean.type], tail: Value[SBoolean.type]*): XorOf = apply(head +: tail) } @@ -248,7 +248,7 @@ object AND extends LogicalTransformerCompanion { override def argInfos: Seq[ArgInfo] = Operations.ANDInfo.argInfos def apply(children: Seq[Value[SBoolean.type]]): AND = - AND(ConcreteCollection(children.toIndexedSeq)) + AND(ConcreteCollection.fromSeq(children)) def apply(head: Value[SBoolean.type], tail: Value[SBoolean.type]*): AND = apply(head +: tail) } @@ -272,7 +272,7 @@ object AtLeast extends ValueCompanion { val MaxChildrenCount: Int = SigmaConstants.MaxChildrenCountForAtLeastOp.value def apply(bound: Value[SInt.type], children: Seq[SigmaPropValue]): AtLeast = - AtLeast(bound, ConcreteCollection(children.toIndexedSeq)) + AtLeast(bound, ConcreteCollection.fromSeq(children)) def apply(bound: Value[SInt.type], head: SigmaPropValue, tail: SigmaPropValue*): AtLeast = apply(bound, head +: tail) diff --git a/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala b/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala index 11d0d0bfb1..f3a877150c 100644 --- a/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala +++ b/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala @@ -118,7 +118,7 @@ object Fold extends ValueCompanion { def concat[T <: SType](input: Value[SCollection[SCollection[T]]])(implicit tT: T): Fold[SCollection[T], T] = { val tColl = SCollection(tT) Fold[SCollection[T], T](input, - ConcreteCollection()(tT).asValue[T], + ConcreteCollection(Array[Value[T]](), tT).asValue[T], FuncValue(Vector((1, tColl), (2, tColl)), Append(ValUse(1, tColl), ValUse(2, tColl))) ) } diff --git a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala index 8e4729bfa4..fbac4b6e2e 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/LangTests.scala @@ -58,8 +58,8 @@ trait LangTests extends Matchers { "b2" -> 2.toByte, "arr1" -> arr1, "arr2" -> arr2, - "col1" -> ConcreteCollection(LongConstant(1), LongConstant(2)), - "col2" -> ConcreteCollection(LongConstant(10), LongConstant(20)), + "col1" -> ConcreteCollection.fromItems(LongConstant(1), LongConstant(2)), + "col2" -> ConcreteCollection.fromItems(LongConstant(10), LongConstant(20)), "g1" -> g1, "g2" -> g2, "p1" -> p1, diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala index 768210632d..e5a2eb5da1 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala @@ -53,8 +53,8 @@ class SigmaBinderTest extends PropSpec with PropertyChecks with Matchers with La bind(env, "arr1 ++ arr2") shouldBe MethodCallLike(Array[Byte](1, 2), "++", IndexedSeq(Array[Byte](10, 20))) // AppendBytes(Array[Byte](1, 2), Array[Byte](10,20)) bind(env, "col1 ++ col2") shouldBe MethodCallLike( - ConcreteCollection(LongConstant(1), LongConstant(2)), - "++", IndexedSeq(ConcreteCollection(LongConstant(10), LongConstant(20)))) + ConcreteCollection.fromItems(LongConstant(1), LongConstant(2)), + "++", IndexedSeq(ConcreteCollection.fromItems(LongConstant(10), LongConstant(20)))) bind(env, "g1.exp(n1)") shouldBe Apply(Select(GroupElementConstant(g1), "exp"), IndexedSeq(BigIntConstant(n1))) bind(env, "g1 * g2") shouldBe MethodCallLike(SigmaDsl.GroupElement(ecp1), "*", IndexedSeq(ecp2)) @@ -122,10 +122,10 @@ class SigmaBinderTest extends PropSpec with PropertyChecks with Matchers with La bind(env, "{val X: (Int, Boolean) = (10, true); 3 > 2}") shouldBe Block(Val("X", STuple(SInt, SBoolean), Tuple(IntConstant(10), TrueLeaf)), GT(3, 2)) bind(env, "{val X: Coll[Int] = Coll(1,2,3); X.size}") shouldBe - Block(Val("X", SCollection(SInt), ConcreteCollection(IndexedSeq(IntConstant(1), IntConstant(2), IntConstant(3)))), + Block(Val("X", SCollection(SInt), ConcreteCollection.fromSeq(Seq(IntConstant(1), IntConstant(2), IntConstant(3)))), Select(Ident("X"), "size")) bind(env, "{val X: (Coll[Int], Box) = (Coll(1,2,3), INPUT); X._1}") shouldBe - Block(Val("X", STuple(SCollection(SInt), SBox), Tuple(ConcreteCollection(IndexedSeq(IntConstant(1), IntConstant(2), IntConstant(3))), Ident("INPUT"))), + Block(Val("X", STuple(SCollection(SInt), SBox), Tuple(ConcreteCollection.fromSeq(Seq(IntConstant(1), IntConstant(2), IntConstant(3))), Ident("INPUT"))), Select(Ident("X"), "_1")) } @@ -191,7 +191,7 @@ class SigmaBinderTest extends PropSpec with PropertyChecks with Matchers with La bind(env, "f[Int](10)") shouldBe Apply(ApplyTypes(Ident("f"), Seq(SInt)), IndexedSeq(IntConstant(10))) bind(env, "INPUTS.map[Int]") shouldBe ApplyTypes(Select(Inputs, "map"), Seq(SInt)) bind(env, "INPUTS.map[Int](10)") shouldBe Apply(ApplyTypes(Select(Inputs, "map"), Seq(SInt)), IndexedSeq(IntConstant(10))) - bind(env, "Coll[Int]()") shouldBe ConcreteCollection()(SInt) + bind(env, "Coll[Int]()") shouldBe ConcreteCollection.fromItems()(SInt) } property("val fails (already defined in env)") { diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala index fdcb3bdc7a..078dd161c7 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala @@ -52,34 +52,34 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe property("array indexed access") { comp(env, "Coll(1)(0)") shouldBe - ByIndex(ConcreteCollection(IndexedSeq(IntConstant(1)))(SInt), 0) + ByIndex(ConcreteCollection.fromSeq(Array(IntConstant(1)))(SInt), 0) comp(env, "Coll(Coll(1))(0)(0)") shouldBe - ByIndex(ByIndex(ConcreteCollection(IndexedSeq(ConcreteCollection(IndexedSeq(IntConstant(1)))))(SCollection(SInt)), 0), 0) + ByIndex(ByIndex(ConcreteCollection.fromSeq(Array(ConcreteCollection.fromItems(IntConstant(1))))(SCollection(SInt)), 0), 0) comp(env, "arr1(0)") shouldBe ByIndex(ByteArrayConstant(Array[Byte](1, 2)), 0) } property("array indexed access with default value") { comp(env, "Coll(1).getOrElse(0, 1)") shouldBe - ByIndex(ConcreteCollection(IndexedSeq(IntConstant(1)))(SInt), 0, Some(IntConstant(1))) + ByIndex(ConcreteCollection.fromSeq(Array(IntConstant(1)))(SInt), 0, Some(IntConstant(1))) comp(env, "Coll(Coll(1)).getOrElse(0, Coll(2))(0)") shouldBe ByIndex( ByIndex( - ConcreteCollection(IndexedSeq(ConcreteCollection(IndexedSeq(IntConstant(1)))))(SCollection(SInt)), + ConcreteCollection.fromSeq(Array(ConcreteCollection.fromSeq(Array(IntConstant(1)))))(SCollection(SInt)), 0, - Some(ConcreteCollection(Vector(IntConstant(2))))), + Some(ConcreteCollection.fromSeq(Array(IntConstant(2))))), 0) comp(env, "arr1.getOrElse(999, 0.toByte)") shouldBe ByIndex(ByteArrayConstant(Array[Byte](1, 2)), IntConstant(999), Some(ByteConstant(0))) } property("predefined functions") { - comp(env, "anyOf(Coll(c1, c2))") shouldBe OR(ConcreteCollection(Vector(TrueLeaf, FalseLeaf))) + comp(env, "anyOf(Coll(c1, c2))") shouldBe OR(ConcreteCollection.fromSeq(Array(TrueLeaf, FalseLeaf))) comp(env, "blake2b256(getVar[Coll[Byte]](10).get)") shouldBe CalcBlake2b256(GetVarByteArray(10).get) comp(env, "sha256(getVar[Coll[Byte]](10).get)") shouldBe CalcSha256(GetVarByteArray(10).get) comp(env, "10.toByte") shouldBe ByteConstant(10) comp(env, "Coll(1)(0).toByte") shouldBe Downcast(ByIndex(ConcreteCollection(Vector(IntConstant(1)),SInt),IntConstant(0),None), SByte) - comp(env, "allOf(Coll(c1, c2))") shouldBe AND(ConcreteCollection(Vector(TrueLeaf, FalseLeaf))) + comp(env, "allOf(Coll(c1, c2))") shouldBe AND(ConcreteCollection.fromSeq(Array(TrueLeaf, FalseLeaf))) comp(env, "getVar[Byte](10).get") shouldBe GetVarByte(10).get comp(env, "getVar[Coll[Byte]](10).get") shouldBe GetVarByteArray(10).get } @@ -175,7 +175,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe } property("decodePoint") { - comp(env, "decodePoint(Coll[Byte](1.toByte))") shouldBe DecodePoint(ConcreteCollection(ByteConstant(1))) + comp(env, "decodePoint(Coll[Byte](1.toByte))") shouldBe DecodePoint(ConcreteCollection.fromItems(ByteConstant(1))) } property("logicalNot") { @@ -225,7 +225,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("Collection.BitShiftLeft") { comp("Coll(1,2) << 2") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.BitShiftLeftMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), Vector(IntConstant(2)), Map()) } @@ -234,7 +234,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("Collection.BitShiftRight") { testMissingCosting("Coll(1,2) >> 2", mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.BitShiftRightMethod, Vector(IntConstant(2)), Map(SCollection.tIV -> SInt)) @@ -245,7 +245,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("Collection.BitShiftRightZeroed") { comp("Coll(true, false) >>> 2") shouldBe mkMethodCall( - ConcreteCollection(TrueLeaf, FalseLeaf), + ConcreteCollection.fromItems(TrueLeaf, FalseLeaf), SCollection.BitShiftRightZeroedMethod, Vector(IntConstant(2)) ) @@ -254,7 +254,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe property("Collection.indices") { comp("Coll(true, false).indices") shouldBe mkMethodCall( - ConcreteCollection(TrueLeaf, FalseLeaf), + ConcreteCollection.fromItems(TrueLeaf, FalseLeaf), SCollection.IndicesMethod.withConcreteTypes(Map(SCollection.tIV -> SBoolean)), Vector() ) @@ -350,16 +350,16 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe property("SCollection.patch") { comp("Coll(1, 2).patch(1, Coll(3), 1)") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.PatchMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), - Vector(IntConstant(1), ConcreteCollection(IntConstant(3)), IntConstant(1)), + Vector(IntConstant(1), ConcreteCollection.fromItems(IntConstant(3)), IntConstant(1)), Map()) } property("SCollection.updated") { comp("Coll(1, 2).updated(1, 1)") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.UpdatedMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), Vector(IntConstant(1), IntConstant(1)), Map()) @@ -368,9 +368,9 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe property("SCollection.updateMany") { comp("Coll(1, 2).updateMany(Coll(1), Coll(3))") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.UpdateManyMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), - Vector(ConcreteCollection(IntConstant(1)), ConcreteCollection(IntConstant(3))), + Vector(ConcreteCollection.fromItems(IntConstant(1)), ConcreteCollection.fromItems(IntConstant(3))), Map()) } @@ -378,9 +378,9 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("SCollection.unionSets") { comp("Coll(1, 2).unionSets(Coll(1))") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.UnionSetsMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), - Vector(ConcreteCollection(IntConstant(1))), + Vector(ConcreteCollection.fromItems(IntConstant(1))), Map()) } @@ -388,9 +388,9 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("SCollection.diff") { comp("Coll(1, 2).diff(Coll(1))") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.DiffMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), - Vector(ConcreteCollection(IntConstant(1))), + Vector(ConcreteCollection.fromItems(IntConstant(1))), Map()) } @@ -398,9 +398,9 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("SCollection.intersect") { comp("Coll(1, 2).intersect(Coll(1))") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.IntersectMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), - Vector(ConcreteCollection(IntConstant(1))), + Vector(ConcreteCollection.fromItems(IntConstant(1))), Map()) } @@ -421,7 +421,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe property("SCollection.indexOf") { comp("Coll(1, 2).indexOf(1, 0)") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.IndexOfMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), Vector(IntConstant(1), IntConstant(0)), Map()) @@ -431,7 +431,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("SCollection.lastIndexOf") { comp("Coll(1, 2).lastIndexOf(1, 0)") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.LastIndexOfMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), Vector(IntConstant(1), IntConstant(0)), Map()) @@ -455,7 +455,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("Collection.distinct") { comp("Coll(true, false).distinct") shouldBe mkMethodCall( - ConcreteCollection(TrueLeaf, FalseLeaf), + ConcreteCollection.fromItems(TrueLeaf, FalseLeaf), SCollection.DistinctMethod.withConcreteTypes(Map(SCollection.tIV -> SBoolean)), Vector() ) @@ -465,9 +465,9 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("SCollection.startsWith") { comp("Coll(1, 2).startsWith(Coll(1), 1)") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.StartsWithMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), - Vector(ConcreteCollection(IntConstant(1)), IntConstant(1)), + Vector(ConcreteCollection.fromItems(IntConstant(1)), IntConstant(1)), Map()) } @@ -475,18 +475,18 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe ignore("SCollection.endsWith") { comp("Coll(1, 2).endsWith(Coll(1))") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.EndsWithMethod.withConcreteTypes(Map(SCollection.tIV -> SInt)), - Vector(ConcreteCollection(IntConstant(1))), + Vector(ConcreteCollection.fromItems(IntConstant(1))), Map()) } property("SCollection.zip") { comp("Coll(1, 2).zip(Coll(1, 1))") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.ZipMethod.withConcreteTypes(Map(SCollection.tIV -> SInt, SCollection.tOV -> SInt)), - Vector(ConcreteCollection(IntConstant(1), IntConstant(1))) + Vector(ConcreteCollection.fromItems(IntConstant(1), IntConstant(1))) ) } @@ -495,7 +495,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe comp( "Coll(1, 2).mapReduce({ (i: Int) => (i > 0, i.toLong) }, { (tl: (Long, Long)) => tl._1 + tl._2 })") shouldBe mkMethodCall( - ConcreteCollection(IntConstant(1), IntConstant(2)), + ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), SCollection.MapReduceMethod.withConcreteTypes(Map(SCollection.tIV -> SInt, SCollection.tK -> SBoolean, SCollection.tV -> SLong)), Vector( Lambda(List(), diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala index f2df51b77a..0676afcc8f 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala @@ -106,11 +106,11 @@ class SigmaSpecializerTest extends PropSpec spec("OUTPUTS.forall({ (out: Box) => out.value >= 10 })") shouldBe ForAll(Outputs, Lambda(Vector(("out", SBox)), SBoolean, GE(ExtractAmount(Ident("out", SBox).asBox), LongConstant(10)))) spec("{ val arr = Coll(1,2); arr.fold(0, { (n1: Int, n2: Int) => n1 + n2 })}") shouldBe - Fold(ConcreteCollection(IntConstant(1), IntConstant(2)), + Fold(ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), IntConstant(0), Lambda(Vector(("n1", SInt), ("n2", SInt)), SInt, Plus(Ident("n1", SInt).asNumValue, Ident("n2", SInt).asNumValue))) spec("{ val arr = Coll(1,2); arr.fold(true, {(n1: Boolean, n2: Int) => n1 && (n2 > 1)})}") shouldBe - Fold(ConcreteCollection(IntConstant(1), IntConstant(2)), + Fold(ConcreteCollection.fromItems(IntConstant(1), IntConstant(2)), TrueLeaf, Lambda(Vector(("n1", SBoolean), ("n2", SInt)), SBoolean, BinAnd(Ident("n1", SBoolean).asBoolValue, GT(Ident("n2", SInt), IntConstant(1)))) diff --git a/sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala index 1d7f96638c..08547d0688 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala @@ -38,14 +38,14 @@ class ConcreteCollectionSerializerSpecification extends TableSerializationSpecif property("ConcreteCollection: Serializer round trip with different types seq") { forAll { (i: IntConstant, ti: TaggedInt) => - val seq = Random.shuffle(IndexedSeq(i.asIntValue, ti.asIntValue)) - roundTripTest(ConcreteCollection(seq)) + val seq = Random.shuffle(Seq(i.asIntValue, ti.asIntValue)) + roundTripTest(ConcreteCollection.fromSeq(seq)) } } override def objects = Table( ("object", "bytes"), - (ConcreteCollection(TrueLeaf, FalseLeaf, TrueLeaf), + (ConcreteCollection.fromItems(TrueLeaf, FalseLeaf, TrueLeaf), Array[Byte](OpCodes.ConcreteCollectionBooleanConstantCode, 3, 5)) // bits: 00000101 ) diff --git a/sigmastate/src/test/scala/sigmastate/serialization/generators/ConcreteCollectionGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ConcreteCollectionGenerators.scala index 1b25fa066a..2322bbcd85 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/generators/ConcreteCollectionGenerators.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/generators/ConcreteCollectionGenerators.scala @@ -2,7 +2,7 @@ package sigmastate.serialization.generators import org.scalacheck.{Arbitrary, Gen} import sigmastate._ -import sigmastate.Values.{ConcreteCollection, EvaluatedValue, Value} +import sigmastate.Values.{ConcreteCollection, Value, EvaluatedValue, IntConstant} trait ConcreteCollectionGenerators { self: ObjectGenerators => val minCollLength = 1 @@ -13,12 +13,12 @@ trait ConcreteCollectionGenerators { self: ObjectGenerators => size <- Gen.chooseNum(minCollLength, maxCollLength) c <- constGen listOfConsts <- Gen.listOfN(size, constGen) - } yield ConcreteCollection(listOfConsts.toIndexedSeq)(c.tpe) + } yield ConcreteCollection(listOfConsts.toArray[Value[T]], c.tpe) val intConstCollectionGen: Gen[ConcreteCollection[SInt.type]] = for { size <- Gen.chooseNum(minCollLength, maxCollLength) listOfConstInts <- Gen.listOfN(size, intConstGen) - } yield ConcreteCollection(listOfConstInts.toIndexedSeq) + } yield ConcreteCollection.fromSeq(listOfConstInts.toArray[IntConstant]) implicit val arbCCOfIntConstant: Arbitrary[ConcreteCollection[SInt.type]] = Arbitrary(intConstCollectionGen) implicit val arbCCOfBoolConstant: Arbitrary[ConcreteCollection[SBoolean.type]] = Arbitrary(concreteCollectionGen[SBoolean.type](booleanConstGen)) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala index eefa1df334..e6c80cf30e 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala @@ -358,7 +358,7 @@ class AVLTreeScriptsSpecification extends SigmaTestingCommons { suite => val treeData = SigmaDsl.avlTree(new AvlTreeData(digest, AvlTreeFlags.ReadOnly, 32, None)) val env = Map("proofId" -> proofId.toLong, - "keys" -> ConcreteCollection(genKey("3"), genKey("4"), genKey("5"))) + "keys" -> ConcreteCollection.fromItems(genKey("3"), genKey("4"), genKey("5"))) val prop = compile(env, """{ | val tree = SELF.R4[AvlTree].get diff --git a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 0751d252b9..805ebdf29e 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -448,7 +448,7 @@ class BasicOpsSpecification extends SigmaTestingCommons { ignore("ByteArrayToBigInt: big int should always be positive") { test("BATBI1", env, ext, "{ byteArrayToBigInt(Coll[Byte](-1.toByte)) > 0 }", - GT(ByteArrayToBigInt(ConcreteCollection(ByteConstant(-1))), BigIntConstant(0)).toSigmaProp, + GT(ByteArrayToBigInt(ConcreteCollection.fromItems(ByteConstant(-1))), BigIntConstant(0)).toSigmaProp, onlyPositive = true ) } @@ -461,7 +461,7 @@ class BasicOpsSpecification extends SigmaTestingCommons { assertExceptionThrown( test("BATBI1", env, ext, s"{ byteArrayToBigInt(Coll[Byte]($itemsStr)) > 0 }", - GT(ByteArrayToBigInt(ConcreteCollection(bytes.map(ByteConstant(_)))), BigIntConstant(0)).toSigmaProp, + GT(ByteArrayToBigInt(ConcreteCollection.fromSeq(bytes.map(ByteConstant(_)))), BigIntConstant(0)).toSigmaProp, onlyPositive = true ), e => rootCause(e).isInstanceOf[ArithmeticException] @@ -476,14 +476,14 @@ class BasicOpsSpecification extends SigmaTestingCommons { assertExceptionThrown( test("BATBI1", env, ext, s"{ byteArrayToBigInt(Coll[Byte]($itemsStr)) != 0 }", - NEQ(ByteArrayToBigInt(ConcreteCollection(bytes.map(ByteConstant(_)))), BigIntConstant(0)).toSigmaProp, + NEQ(ByteArrayToBigInt(ConcreteCollection.fromSeq(bytes.map(ByteConstant(_)))), BigIntConstant(0)).toSigmaProp, onlyPositive = true ), e => rootCause(e).isInstanceOf[ArithmeticException]) else test("BATBI1", env, ext, s"{ byteArrayToBigInt(Coll[Byte]($itemsStr)) != 0 }", - NEQ(ByteArrayToBigInt(ConcreteCollection(bytes.map(ByteConstant(_)))), BigIntConstant(0)).toSigmaProp, + NEQ(ByteArrayToBigInt(ConcreteCollection.fromSeq(bytes.map(ByteConstant(_)))), BigIntConstant(0)).toSigmaProp, onlyPositive = true ) } diff --git a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala index 9af0ab0480..1c22f04ad2 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala @@ -488,7 +488,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { property("indices") { assertProof("OUTPUTS.indices == Coll(0, 1)", - EQ(MethodCall(Outputs, IndicesMethod.withConcreteTypes(Map(tIV -> SBox)), Vector(), Map()), ConcreteCollection(IntConstant(0), IntConstant(1))), + EQ(MethodCall(Outputs, IndicesMethod.withConcreteTypes(Map(tIV -> SBox)), Vector(), Map()), ConcreteCollection.fromItems(IntConstant(0), IntConstant(1))), IndexedSeq(1L, 1L)) } @@ -519,7 +519,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { MethodCall( MapCollection(Outputs, FuncValue(Vector((1, SBox)), ExtractAmount(ValUse(1, SBox)))), PatchMethod.withConcreteTypes(Map(tIV -> SLong)), - Vector(IntConstant(0), ConcreteCollection(LongConstant(3)), IntConstant(1)), + Vector(IntConstant(0), ConcreteCollection.fromItems(LongConstant(3)), IntConstant(1)), Map()).asCollection[SType], IntConstant(0) ), @@ -549,7 +549,7 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { MethodCall( MapCollection(Outputs, FuncValue(Vector((1, SBox)), ExtractAmount(ValUse(1, SBox)))), UpdateManyMethod.withConcreteTypes(Map(tIV -> SLong)), - Vector(ConcreteCollection(IntConstant(0)), ConcreteCollection(LongConstant(3))), + Vector(ConcreteCollection.fromItems(IntConstant(0)), ConcreteCollection.fromItems(LongConstant(3))), Map()).asCollection[SType], IntConstant(0) ), diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala index 213cad5606..1a2ddc93c1 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/FsmExampleSpecification.scala @@ -88,7 +88,7 @@ class FsmExampleSpecification extends SigmaTestingCommons { OptionGet(ExtractRegisterAs[SAvlTree.type](Self, fsmDescRegister)), SAvlTree.getMethod, IndexedSeq(Append( - ConcreteCollection[SByte.type]( + ConcreteCollection.fromItems[SByte.type]( OptionGet(ExtractRegisterAs[SByte.type](Self, currentStateRegister)), OptionGetOrElse(ExtractRegisterAs[SByte.type](ByIndex(Outputs, IntConstant.Zero), currentStateRegister),ByteConstant(-1))), From bbea9f0231f4ce88edf85fbc5133e63af90e3f6a Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 29 Oct 2019 01:44:02 +0300 Subject: [PATCH 06/16] optimized ConcreteCollectionBooleanConstantSerializer.scala --- .../org/ergoplatform/ErgoScriptPredef.scala | 2 +- .../src/main/scala/sigmastate/Values.scala | 1 + .../serialization/ApplySerializer.scala | 7 +++++-- .../BoolToSigmaPropSerializer.scala | 6 ++++-- ...reteCollectionBooleanConstantSerializer.scala | 16 +++++++++++----- .../LogicalTransformerSerializer.scala | 6 ++++-- .../trees/Relation2Serializer.scala | 14 ++++++++------ .../scala/sigmastate/utxo/transformers.scala | 2 +- .../sigmastate/lang/SigmaCompilerTest.scala | 4 ++-- .../scala/sigmastate/lang/SigmaTyperTest.scala | 2 +- .../SubstConstantsSerializerSpecification.scala | 2 +- .../sigmastate/utxo/ThresholdSpecification.scala | 2 +- 12 files changed, 40 insertions(+), 24 deletions(-) diff --git a/sigmastate/src/main/scala/org/ergoplatform/ErgoScriptPredef.scala b/sigmastate/src/main/scala/org/ergoplatform/ErgoScriptPredef.scala index c5e03de489..4cbcb555f0 100644 --- a/sigmastate/src/main/scala/org/ergoplatform/ErgoScriptPredef.scala +++ b/sigmastate/src/main/scala/org/ergoplatform/ErgoScriptPredef.scala @@ -41,7 +41,7 @@ object ErgoScriptPredef { // first segregated constant is delta, so key is second constant val positions = IntArrayConstant(Array[Int](1)) val minerPubkeySigmaProp = CreateProveDlog(DecodePoint(minerPkBytesVal)) - val newVals = Values.ConcreteCollection(Vector[SigmaPropValue](minerPubkeySigmaProp), SSigmaProp) + val newVals = Values.ConcreteCollection(Array[SigmaPropValue](minerPubkeySigmaProp), SSigmaProp) SubstConstants(genericMinerPropBytes, positions, newVals) } diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index 368cd68f8d..8344ce73a3 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -684,6 +684,7 @@ object Values { } object ConcreteCollection extends ValueCompanion { override def opCode: OpCode = ConcreteCollectionCode + def fromSeq[V <: SType](items: Seq[Value[V]])(implicit tV: V): ConcreteCollection[V] = ConcreteCollection(items, tV) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala index 38b0127c50..dea074c1ea 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala @@ -3,16 +3,19 @@ package sigmastate.serialization import sigmastate.Values._ import sigmastate._ import sigmastate.lang.Terms.Apply +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} case class ApplySerializer(cons: (Value[SType], IndexedSeq[Value[SType]]) => Value[SType]) extends ValueSerializer[Apply] { import sigmastate.Operations.ApplyInfo._ override def opDesc = Apply + val funcInfo: DataInfo[SValue] = funcArg + val argsInfo: DataInfo[Seq[SValue]] = argsArg override def serialize(obj: Apply, w: SigmaByteWriter): Unit = { - w.putValue(obj.func, funcArg) - w.putValues(obj.args, argsArg) + w.putValue(obj.func, funcInfo) + w.putValues(obj.args, argsInfo) } override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/BoolToSigmaPropSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/BoolToSigmaPropSerializer.scala index 4c684af3b4..bb3a282935 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/BoolToSigmaPropSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/BoolToSigmaPropSerializer.scala @@ -1,16 +1,18 @@ package sigmastate.serialization -import sigmastate.Values.{BoolValue, SigmaPropValue} +import sigmastate.Values.{BoolValue, SigmaPropValue, SValue} import sigmastate.lang.Terms._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.{BoolToSigmaProp, SType, Values} case class BoolToSigmaPropSerializer(cons: BoolValue => SigmaPropValue) extends ValueSerializer[BoolToSigmaProp] { import sigmastate.Operations.BoolToSigmaPropInfo._ override def opDesc = BoolToSigmaProp + val conditionInfo: DataInfo[SValue] = conditionArg def serialize(obj: BoolToSigmaProp, w: SigmaByteWriter): Unit = { - w.putValue(obj.value, conditionArg) + w.putValue(obj.value, conditionInfo) } def parse(r: SigmaByteReader): Values.Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionBooleanConstantSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionBooleanConstantSerializer.scala index 03b967d664..1d4b402c94 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionBooleanConstantSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionBooleanConstantSerializer.scala @@ -9,15 +9,21 @@ import spire.syntax.all.cfor case class ConcreteCollectionBooleanConstantSerializer(cons: (IndexedSeq[Value[SBoolean.type]], SBoolean.type) => Value[SCollection[SBoolean.type]]) extends ValueSerializer[ConcreteCollection[SBoolean.type]] { override def opDesc = ConcreteCollectionBooleanConstant + val numBitsInfo: DataInfo[Vlq[U[Short]]] = ArgInfo("numBits", "number of items in a collection of Boolean values") + val bitsInfo: DataInfo[Bits] = maxBitsInfo("bits", 0x1FFF, "Boolean values encoded as as bits (right most byte is zero-padded on the right)") override def serialize(cc: ConcreteCollection[SBoolean.type], w: SigmaByteWriter): Unit = { - w.putUShort(cc.items.size, ArgInfo("numBits", "number of items in a collection of Boolean values")) - w.putBits( - cc.items.map { + val items = cc.items + val len = items.length + w.putUShort(len, numBitsInfo) + val bits = new Array[Boolean](len) + cfor(0)(_ < len, _ + 1) { i => + bits(i) = items(i) match { case v: BooleanConstant => v.value case v => error(s"Expected collection of BooleanConstant values, got: $v") - }.toArray, - maxBitsInfo("bits", 0x1FFF, "Boolean values encoded as as bits (right most byte is zero-padded on the right)")) + } + } + w.putBits(bits, bitsInfo) } /** @hotspot don't beautify this code */ diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/LogicalTransformerSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/LogicalTransformerSerializer.scala index 800b5a1508..18b251f483 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/LogicalTransformerSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/LogicalTransformerSerializer.scala @@ -1,8 +1,9 @@ package sigmastate.serialization.transformers -import sigmastate.Values.{Value, ValueCompanion} +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.Transformer import sigmastate.{SCollection, SBoolean, LogicalTransformerCompanion} @@ -11,9 +12,10 @@ case class LogicalTransformerSerializer[I <: SCollection[SBoolean.type], O <: SB (opDesc: LogicalTransformerCompanion, cons: Value[SCollection[SBoolean.type]] => Value[SBoolean.type]) extends ValueSerializer[Transformer[I, O]] { + val inputInfo: DataInfo[SValue] = opDesc.argInfos(0) override def serialize(obj: Transformer[I, O], w: SigmaByteWriter): Unit = - w.putValue(obj.input, opDesc.argInfos(0)) + w.putValue(obj.input, inputInfo) override def parse(r: SigmaByteReader): Value[SBoolean.type] = cons(r.getValue().asCollection[SBoolean.type]) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala index 7263190e01..58345a08cd 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/trees/Relation2Serializer.scala @@ -12,6 +12,10 @@ case class Relation2Serializer[S1 <: SType, S2 <: SType, R <: Value[SBoolean.typ (override val opDesc: RelationCompanion, constructor: (Value[S1], Value[S2]) => Value[SBoolean.type]) extends ValueSerializer[R] { import SigmaByteWriter._ + val opCodeInfo: DataInfo[Byte] = ArgInfo("opCode", s"always contains OpCode ${ConcreteCollectionBooleanConstantCode.toUByte}") + val bitsInfo: DataInfo[Bits] = maxBitsInfo("(l,r)", 2, "two higher bits in a byte") + val leftArgInfo: DataInfo[SValue] = opDesc.argInfos(0) + val rightArgInfo: DataInfo[SValue] = opDesc.argInfos(1) override def serialize(obj: R, w: SigmaByteWriter): Unit = { val typedRel = obj.asInstanceOf[Relation[S1, S2]] @@ -19,15 +23,13 @@ case class Relation2Serializer[S1 <: SType, S2 <: SType, R <: Value[SBoolean.typ (typedRel.left, typedRel.right) match { case (Constant(left, lTpe), Constant(right, rTpe)) if lTpe == SBoolean && rTpe == SBoolean => when(1, "(Constant(l, Boolean), Constant(r, Boolean))") { - w.put(ConcreteCollectionBooleanConstantCode, ArgInfo("opCode", s"always contains OpCode ${ConcreteCollectionBooleanConstantCode.toUByte}")) - w.putBits( - Array[Boolean](left.asInstanceOf[Boolean], right.asInstanceOf[Boolean]), - maxBitsInfo("(l,r)", 2, "two higher bits in a byte")) + w.put(ConcreteCollectionBooleanConstantCode, opCodeInfo) + w.putBits(Array(left.asInstanceOf[Boolean], right.asInstanceOf[Boolean]), bitsInfo) } case _ => otherwise { - w.putValue(typedRel.left, opDesc.argInfos(0)) - w.putValue(typedRel.right, opDesc.argInfos(1)) + w.putValue(typedRel.left, leftArgInfo) + w.putValue(typedRel.right, rightArgInfo) } } } diff --git a/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala b/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala index f3a877150c..d9146ded39 100644 --- a/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala +++ b/sigmastate/src/main/scala/sigmastate/utxo/transformers.scala @@ -119,7 +119,7 @@ object Fold extends ValueCompanion { val tColl = SCollection(tT) Fold[SCollection[T], T](input, ConcreteCollection(Array[Value[T]](), tT).asValue[T], - FuncValue(Vector((1, tColl), (2, tColl)), Append(ValUse(1, tColl), ValUse(2, tColl))) + FuncValue(Array((1, tColl), (2, tColl)), Append(ValUse(1, tColl), ValUse(2, tColl))) ) } } diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala index 078dd161c7..a4f1ecc3dc 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala @@ -78,7 +78,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe comp(env, "sha256(getVar[Coll[Byte]](10).get)") shouldBe CalcSha256(GetVarByteArray(10).get) comp(env, "10.toByte") shouldBe ByteConstant(10) comp(env, "Coll(1)(0).toByte") shouldBe - Downcast(ByIndex(ConcreteCollection(Vector(IntConstant(1)),SInt),IntConstant(0),None), SByte) + Downcast(ByIndex(ConcreteCollection(Array(IntConstant(1)),SInt),IntConstant(0),None), SByte) comp(env, "allOf(Coll(c1, c2))") shouldBe AND(ConcreteCollection.fromSeq(Array(TrueLeaf, FalseLeaf))) comp(env, "getVar[Byte](10).get") shouldBe GetVarByte(10).get comp(env, "getVar[Coll[Byte]](10).get") shouldBe GetVarByteArray(10).get @@ -266,7 +266,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe mkMethodCall(Outputs, SCollection.FlatMapMethod.withConcreteTypes(Map(SCollection.tIV -> SBox, SCollection.tOV -> SBoolean)), Vector(FuncValue(1,SBox, - ConcreteCollection(Vector(GE(ExtractAmount(ValUse(1, SBox)), LongConstant(1))), SBoolean))), Map()) + ConcreteCollection(Array(GE(ExtractAmount(ValUse(1, SBox)), LongConstant(1))), SBoolean))), Map()) } // TODO soft-fork: related to https://github.com/ScorexFoundation/sigmastate-interpreter/issues/486 diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala index 3482ed1e46..93cad502d1 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaTyperTest.scala @@ -670,7 +670,7 @@ class SigmaTyperTest extends PropSpec with PropertyChecks with Matchers with Lan val script2 = script(pk2) val inputBytes = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(script1.treeWithSegregation) val positions = IntArrayConstant(Array[Int](2)) - val newVals = ConcreteCollection(Vector[SigmaPropValue](SigmaPropConstant(pk2)), SSigmaProp) + val newVals = ConcreteCollection(Array[SigmaPropValue](SigmaPropConstant(pk2)), SSigmaProp) val expectedBytes = ErgoTreeSerializer.DefaultSerializer.serializeErgoTree(script2.treeWithSegregation) diff --git a/sigmastate/src/test/scala/sigmastate/serialization/SubstConstantsSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/SubstConstantsSerializerSpecification.scala index b573d06758..43d90f55ee 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/SubstConstantsSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/SubstConstantsSerializerSpecification.scala @@ -10,7 +10,7 @@ class SubstConstantsSerializerSpecification extends SerializationSpecification { forAll(numExprTreeNodeGen) { prop => val tree = EQ(prop, IntConstant(1)).toSigmaProp.treeWithSegregation val bytes = DefaultSerializer.serializeErgoTree(tree) - val newVals = ConcreteCollection(Vector[IntValue](1), SInt) + val newVals = ConcreteCollection(Array[IntValue](1), SInt) val expr = SubstConstants(bytes, IntArrayConstant(Array(0)), newVals) roundTripTest(expr) } diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala index f7fd2eff31..6a84228622 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala @@ -58,7 +58,7 @@ class ThresholdSpecification extends SigmaTestingCommons { val prop2 = AtLeast(IntConstant(3), - ConcreteCollection(Vector[SigmaPropValue](pubkeyA, pubkeyB, pubkeyC), SSigmaProp)) + ConcreteCollection(Array[SigmaPropValue](pubkeyA, pubkeyB, pubkeyC), SSigmaProp)) compiledProp2 shouldBe prop2 val proof = proverABC.prove(compiledProp2, ctx, fakeMessage).get From 50bcd0a25837a8024fc65bd27ed787180462708f Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 29 Oct 2019 11:03:01 +0300 Subject: [PATCH 07/16] optimized BlockValueSerializer --- .../serialization/BlockValueSerializer.scala | 13 ++++++++----- .../ConcreteCollectionSerializer.scala | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/BlockValueSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/BlockValueSerializer.scala index a8686bc140..b595af5740 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/BlockValueSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/BlockValueSerializer.scala @@ -5,18 +5,21 @@ import sigmastate._ import scorex.util.Extensions._ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import ValueSerializer._ +import sigmastate.utils.SigmaByteWriter.{Vlq, U, DataInfo} case class BlockValueSerializer(cons: (IndexedSeq[BlockItem], Value[SType]) => Value[SType]) extends ValueSerializer[BlockValue] { override def opDesc = BlockValue + val numItemsInfo: DataInfo[Vlq[U[Int]]] = ArgInfo("numItems", "number of block items") + val itemInfo: DataInfo[SValue] = ArgInfo("item_i", "block's item in i-th position") + val resultInfo: DataInfo[SValue] = ArgInfo("result", "result expression of the block") override def serialize(obj: BlockValue, w: SigmaByteWriter): Unit = { - val sizeVar = "numItems" - w.putUInt(obj.items.length, ArgInfo(sizeVar, "number of block items")) - foreach(sizeVar, obj.items){ i => - w.putValue(i, ArgInfo("item_i", "block's item in i-th position")) + w.putUInt(obj.items.length, numItemsInfo) + foreach(numItemsInfo.info.name, obj.items){ i => + w.putValue(i, itemInfo) } - w.putValue(obj.result, ArgInfo("result", "result expression of the block")) + w.putValue(obj.result, resultInfo) } override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala index 7c1596a760..d5e41465a1 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ConcreteCollectionSerializer.scala @@ -18,7 +18,7 @@ case class ConcreteCollectionSerializer(cons: (IndexedSeq[Value[SType]], SType) override def serialize(cc: ConcreteCollection[_ <: SType], w: SigmaByteWriter): Unit = { w.putUShort(cc.items.size, numItemsInfo) w.putType(cc.tpe.elemType, elementTypeInfo) - foreach("numItems", cc.items)(w.putValue(_, itemInfo)) + foreach(numItemsInfo.info.name, cc.items)(w.putValue(_, itemInfo)) } /** @hotspot don't beautify this code */ From 1fd8bec9565ece79963d333d9cf1ed4db8bc8a3b Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 29 Oct 2019 20:44:28 +0300 Subject: [PATCH 08/16] optimized FuncValueSerializer --- .../serialization/FuncValueSerializer.scala | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/FuncValueSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/FuncValueSerializer.scala index 23bb527ede..a5e41fdbb2 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/FuncValueSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/FuncValueSerializer.scala @@ -5,20 +5,25 @@ import sigmastate._ import scorex.util.Extensions._ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import ValueSerializer._ +import sigmastate.utils.SigmaByteWriter.{DataInfo, U, Vlq} import scala.collection.mutable case class FuncValueSerializer(cons: (IndexedSeq[(Int, SType)], Value[SType]) => Value[SType]) extends ValueSerializer[FuncValue] { override def opDesc = FuncValue + val numArgsInfo: DataInfo[Vlq[U[Int]]] = ArgInfo("numArgs", "number of function arguments") + val idInfo: DataInfo[Vlq[U[Int]]] = ArgInfo("id_i", "identifier of the i-th argument") + val typeInfo: DataInfo[SType] = ArgInfo("type_i", "type of the i-th argument") + val bodyInfo: DataInfo[SValue] = ArgInfo("body", "function body, which is parameterized by arguments") override def serialize(obj: FuncValue, w: SigmaByteWriter): Unit = { - w.putUInt(obj.args.length, ArgInfo("numArgs", "number of function arguments")) - foreach("numArgs", obj.args) { case (idx, tpe) => - w.putUInt(idx, ArgInfo("id_i", "identifier of the i-th argument")) - .putType(tpe, ArgInfo("type_i", "type of the i-th argument")) + w.putUInt(obj.args.length, numArgsInfo) + foreach(numArgsInfo.info.name, obj.args) { case (idx, tpe) => + w.putUInt(idx, idInfo) + .putType(tpe, typeInfo) } - w.putValue(obj.body, ArgInfo("body", "function body, which is parameterized by arguments")) + w.putValue(obj.body, bodyInfo) } override def parse(r: SigmaByteReader): Value[SType] = { From 9e4424b62ada075a343a0fe3a283387e06d580e9 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 29 Oct 2019 20:44:45 +0300 Subject: [PATCH 09/16] optimized GetVarSerializer --- .../scala/sigmastate/serialization/GetVarSerializer.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala index 7dee2117ef..a291c9512a 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala @@ -2,6 +2,7 @@ package sigmastate.serialization import sigmastate.Values._ import sigmastate._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.GetVar @@ -9,10 +10,11 @@ case class GetVarSerializer(cons: (Byte, SType) => Value[SOption[SType]]) extends ValueSerializer[GetVar[_ <: SType]] { import sigmastate.Operations.GetVarInfo._ override def opDesc = GetVar + val typeInfo: DataInfo[SType] = ArgInfo("type", "expected type of context variable") override def serialize(obj: GetVar[_ <: SType], w: SigmaByteWriter): Unit = w.put(obj.varId, varIdArg) - .putType(obj.tpe.elemType, ArgInfo("type", "expected type of context variable")) + .putType(obj.tpe.elemType, typeInfo) override def parse(r: SigmaByteReader): Value[SType] = { val varId = r.getByte() From 6b3f5cb4a3053f2e5c0e4cf503bc0f5699fdd418 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 29 Oct 2019 21:01:49 +0300 Subject: [PATCH 10/16] optimized MethodCallSerializer --- .../serialization/MethodCallSerializer.scala | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala index acf13b5078..6ed92dc801 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala @@ -4,6 +4,7 @@ import sigmastate.Values._ import sigmastate._ import sigmastate.lang.SigmaTyper.STypeSubst import sigmastate.lang.Terms.MethodCall +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.ComplexityTable import spire.syntax.all.cfor @@ -11,13 +12,17 @@ import spire.syntax.all.cfor case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[SType]], STypeSubst) => Value[SType]) extends ValueSerializer[MethodCall] { override def opDesc: ValueCompanion = MethodCall + val typeCodeInfo: DataInfo[Byte] = ArgInfo("typeCode", "type of the method (see Table~\\ref{table:predeftypes})") + val methodCodeInfo: DataInfo[Byte] = ArgInfo("methodCode", "a code of the method") + val objInfo: DataInfo[SValue] = ArgInfo("obj", "receiver object of this method call") + val argsInfo: DataInfo[Seq[SValue]] = ArgInfo("args", "arguments of the method call") override def serialize(mc: MethodCall, w: SigmaByteWriter): Unit = { - w.put(mc.method.objType.typeId, ArgInfo("typeCode", "type of the method (see Table~\\ref{table:predeftypes})")) - w.put(mc.method.methodId, ArgInfo("methodCode", "a code of the method")) - w.putValue(mc.obj, ArgInfo("obj", "receiver object of this method call")) + w.put(mc.method.objType.typeId, typeCodeInfo) + w.put(mc.method.methodId, methodCodeInfo) + w.putValue(mc.obj, objInfo) assert(mc.args.nonEmpty) - w.putValues(mc.args, ArgInfo("args", "arguments of the method call")) + w.putValues(mc.args, argsInfo) } override def getComplexity: Int = 0 // because we add it explicitly in parse below From f436d2e4cc7e54ae108e0d4e514e81738fc7f6ec Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 30 Oct 2019 00:50:59 +0300 Subject: [PATCH 11/16] all serializers optimized --- .../serialization/ApplySerializer.scala | 5 +++-- .../serialization/ConstantSerializer.scala | 2 -- .../CreateAvlTreeSerializer.scala | 13 ++++++++---- .../serialization/GetVarSerializer.scala | 3 ++- .../serialization/LogicalNotSerializer.scala | 8 +++++--- .../serialization/MethodCallSerializer.scala | 5 +++-- .../serialization/ModQArithOpSerializer.scala | 11 ++++++---- .../OneArgumentOperationSerializer.scala | 4 +++- .../OptionGetOrElseSerializer.scala | 7 +++++-- .../PropertyCallSerializer.scala | 11 ++++++---- .../serialization/ProveDlogSerializer.scala | 6 ++++-- .../serialization/SelectFieldSerializer.scala | 10 +++++++--- .../SigmaPropBytesSerializer.scala | 5 ++++- .../SubstConstantsSerializer.scala | 16 +++++++++------ .../serialization/TupleSerializer.scala | 11 ++++++---- .../TwoArgumentsSerializer.scala | 9 ++++++--- .../serialization/ValDefSerializer.scala | 11 +++++++--- .../serialization/ValueSerializer.scala | 2 -- .../BooleanTransformerSerializer.scala | 13 +++++++----- .../transformers/ByIndexSerializer.scala | 12 +++++++---- .../DeserializeContextSerializer.scala | 6 ++++-- .../DeserializeRegisterSerializer.scala | 14 ++++++++----- .../ExtractRegisterAsSerializer.scala | 14 ++++++++----- .../transformers/FoldSerializer.scala | 14 ++++++++----- .../MapCollectionSerializer.scala | 9 ++++++--- .../transformers/NumericCastSerializer.scala | 9 ++++++--- .../SigmaTransformerSerializer.scala | 20 ++++++++++--------- .../SimpleTransformerSerializer.scala | 8 +++++--- .../transformers/SliceSerializer.scala | 14 +++++++------ .../trees/QuadrupleSerializer.scala | 10 +++++++--- .../sigmastate/utils/SigmaByteWriter.scala | 14 +++++++++---- 31 files changed, 190 insertions(+), 106 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala index dea074c1ea..89daeb0713 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ApplySerializer.scala @@ -3,7 +3,7 @@ package sigmastate.serialization import sigmastate.Values._ import sigmastate._ import sigmastate.lang.Terms.Apply -import sigmastate.utils.SigmaByteWriter.DataInfo +import sigmastate.utils.SigmaByteWriter._ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} case class ApplySerializer(cons: (Value[SType], IndexedSeq[Value[SType]]) => Value[SType]) @@ -12,10 +12,11 @@ case class ApplySerializer(cons: (Value[SType], IndexedSeq[Value[SType]]) => Val override def opDesc = Apply val funcInfo: DataInfo[SValue] = funcArg val argsInfo: DataInfo[Seq[SValue]] = argsArg + val argsItemInfo: DataInfo[SValue] = valuesItemInfo(argsInfo) override def serialize(obj: Apply, w: SigmaByteWriter): Unit = { w.putValue(obj.func, funcInfo) - w.putValues(obj.args, argsInfo) + w.putValues(obj.args, argsInfo, argsItemInfo) } override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ConstantSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ConstantSerializer.scala index 74f5451904..33fa31cd1f 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ConstantSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ConstantSerializer.scala @@ -3,9 +3,7 @@ package sigmastate.serialization import sigmastate.SType import sigmastate.Values._ import sigmastate.lang.SigmaBuilder -import sigmastate.lang.Terms.OperationId import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} -import sigmastate.utxo.CostTable.Cost /** This works in tandem with DataSerializer, if you change one make sure to check the other.*/ case class ConstantSerializer(builder: SigmaBuilder) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/CreateAvlTreeSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/CreateAvlTreeSerializer.scala index 901e532c9a..efd84f38b6 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/CreateAvlTreeSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/CreateAvlTreeSerializer.scala @@ -6,6 +6,7 @@ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate._ import sigmastate.Values._ import sigmastate.lang.Terms.ValueOps +import sigmastate.utils.SigmaByteWriter.DataInfo case class CreateAvlTreeSerializer( cons: (ByteValue, Value[SByteArray], IntValue, Value[SIntOption]) => AvlTreeValue @@ -14,12 +15,16 @@ case class CreateAvlTreeSerializer( { import sigmastate.Operations.CreateAvlTreeInfo._ override def opDesc = CreateAvlTree + val operationFlagsInfo: DataInfo[SValue] = operationFlagsArg + val digestInfo: DataInfo[SValue] = digestArg + val keyLengthInfo: DataInfo[SValue] = keyLengthArg + val valueLengthOptInfo: DataInfo[SValue] = valueLengthOptArg override def serialize(obj: CreateAvlTree, w: SigmaByteWriter): Unit = { - w.putValue(obj.operationFlags, operationFlagsArg) - w.putValue(obj.digest, digestArg) - w.putValue(obj.keyLength, keyLengthArg) - w.putValue(obj.valueLengthOpt, valueLengthOptArg) + w.putValue(obj.operationFlags, operationFlagsInfo) + w.putValue(obj.digest, digestInfo) + w.putValue(obj.keyLength, keyLengthInfo) + w.putValue(obj.valueLengthOpt, valueLengthOptInfo) } override def parse(r: SigmaByteReader) = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala index a291c9512a..cd9e9872c4 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/GetVarSerializer.scala @@ -11,9 +11,10 @@ case class GetVarSerializer(cons: (Byte, SType) => Value[SOption[SType]]) import sigmastate.Operations.GetVarInfo._ override def opDesc = GetVar val typeInfo: DataInfo[SType] = ArgInfo("type", "expected type of context variable") + val varIdInfo: DataInfo[Byte] = varIdArg override def serialize(obj: GetVar[_ <: SType], w: SigmaByteWriter): Unit = - w.put(obj.varId, varIdArg) + w.put(obj.varId, varIdInfo) .putType(obj.tpe.elemType, typeInfo) override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/LogicalNotSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/LogicalNotSerializer.scala index 0d3603f134..667e8a699f 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/LogicalNotSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/LogicalNotSerializer.scala @@ -1,17 +1,19 @@ package sigmastate.serialization import sigmastate.LogicalNot -import sigmastate.Operations.LogicalNotInfo -import sigmastate.Values.BoolValue +import sigmastate.Operations.LogicalNotInfo.inputArg +import sigmastate.Values.{BoolValue, SValue} import sigmastate.lang.Terms._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} case class LogicalNotSerializer(cons: BoolValue => BoolValue) extends ValueSerializer[LogicalNot] { override def opDesc = LogicalNot + val inputInfo: DataInfo[SValue] = inputArg override def serialize(obj: LogicalNot, w: SigmaByteWriter): Unit = - w.putValue(obj.input, LogicalNotInfo.inputArg) + w.putValue(obj.input, inputInfo) override def parse(r: SigmaByteReader): BoolValue = cons(r.getValue().asBoolValue) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala index 6ed92dc801..17dbc964f6 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/MethodCallSerializer.scala @@ -4,7 +4,7 @@ import sigmastate.Values._ import sigmastate._ import sigmastate.lang.SigmaTyper.STypeSubst import sigmastate.lang.Terms.MethodCall -import sigmastate.utils.SigmaByteWriter.DataInfo +import sigmastate.utils.SigmaByteWriter.{DataInfo, valuesItemInfo} import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.ComplexityTable import spire.syntax.all.cfor @@ -16,13 +16,14 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S val methodCodeInfo: DataInfo[Byte] = ArgInfo("methodCode", "a code of the method") val objInfo: DataInfo[SValue] = ArgInfo("obj", "receiver object of this method call") val argsInfo: DataInfo[Seq[SValue]] = ArgInfo("args", "arguments of the method call") + val argsItemInfo = valuesItemInfo(argsInfo) override def serialize(mc: MethodCall, w: SigmaByteWriter): Unit = { w.put(mc.method.objType.typeId, typeCodeInfo) w.put(mc.method.methodId, methodCodeInfo) w.putValue(mc.obj, objInfo) assert(mc.args.nonEmpty) - w.putValues(mc.args, argsInfo) + w.putValues(mc.args, argsInfo, argsItemInfo) } override def getComplexity: Int = 0 // because we add it explicitly in parse below diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ModQArithOpSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ModQArithOpSerializer.scala index 6726bbb134..9ca556effb 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ModQArithOpSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ModQArithOpSerializer.scala @@ -1,16 +1,19 @@ package sigmastate.serialization -import sigmastate.Values.{BigIntValue, Value} +import sigmastate.Values.{BigIntValue, Value, SValue} import sigmastate.lang.Terms._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} -import sigmastate.{SType, ModQArithOp, ModQArithOpCompanion} +import sigmastate.{ModQArithOpCompanion, SType, ModQArithOp} case class ModQArithOpSerializer(override val opDesc: ModQArithOpCompanion, cons: (BigIntValue, BigIntValue) => BigIntValue) extends ValueSerializer[ModQArithOp] { + val leftInfo: DataInfo[SValue] = opDesc.argInfos(0) + val rightInfo: DataInfo[SValue] = opDesc.argInfos(1) override def serialize(obj: ModQArithOp, w: SigmaByteWriter): Unit = { - w.putValue(obj.left, opDesc.argInfos(0)) - .putValue(obj.right, opDesc.argInfos(1)) + w.putValue(obj.left, leftInfo) + .putValue(obj.right, rightInfo) } override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/OneArgumentOperationSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/OneArgumentOperationSerializer.scala index e85b982b71..fd3fd8c2ea 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/OneArgumentOperationSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/OneArgumentOperationSerializer.scala @@ -2,14 +2,16 @@ package sigmastate.serialization import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.{OneArgumentOperation, OneArgumentOperationCompanion, SType} case class OneArgumentOperationSerializer[T <: SType](opDesc: OneArgumentOperationCompanion, cons: Value[T] => SValue) extends ValueSerializer[OneArgumentOperation[T, SType]] { + val objInfo: DataInfo[SValue] = opDesc.argInfos(0) override def serialize(obj: OneArgumentOperation[T, SType], w: SigmaByteWriter): Unit = - w.putValue(obj.input, opDesc.argInfos(0)) + w.putValue(obj.input, objInfo) override def parse(r: SigmaByteReader): SValue = cons(r.getValue().asValue[T]) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/OptionGetOrElseSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/OptionGetOrElseSerializer.scala index 155f39e2e4..bc0fe694e6 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/OptionGetOrElseSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/OptionGetOrElseSerializer.scala @@ -3,6 +3,7 @@ package sigmastate.serialization import sigmastate.Values._ import sigmastate._ import sigmastate.lang.Terms._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.OptionGetOrElse @@ -10,10 +11,12 @@ case class OptionGetOrElseSerializer(cons: (Value[SOption[SType]], Value[SType]) extends ValueSerializer[OptionGetOrElse[_ <: SType]] { import sigmastate.Operations.OptionGetOrElseInfo._ override def opDesc = OptionGetOrElse + val thisInfo: DataInfo[SValue] = thisArg + val defaultInfo: DataInfo[SValue] = defaultArg override def serialize(obj: OptionGetOrElse[_ <: SType], w: SigmaByteWriter): Unit = - w.putValue(obj.input, thisArg) - .putValue(obj.default, defaultArg) + w.putValue(obj.input, thisInfo) + .putValue(obj.default, defaultInfo) override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/PropertyCallSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/PropertyCallSerializer.scala index ab33c40c79..f382c203e1 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/PropertyCallSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/PropertyCallSerializer.scala @@ -4,19 +4,22 @@ import sigmastate.Values._ import sigmastate._ import sigmastate.lang.SigmaTyper.STypeSubst import sigmastate.lang.Terms.{PropertyCall, MethodCall} +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.ComplexityTable case class PropertyCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[SType]], STypeSubst) => Value[SType]) extends ValueSerializer[MethodCall] { override def opDesc: ValueCompanion = PropertyCall - override def getComplexity: Int = 0 // because we add it explicitly in parse below + val typeCodeInfo: DataInfo[Byte] = ArgInfo("typeCode", "type of the method (see Table~\\ref{table:predeftypes})") + val methodCodeInfo: DataInfo[Byte] = ArgInfo("methodCode", "a code of the property") + val objInfo: DataInfo[SValue] = ArgInfo("obj", "receiver object of this property call") override def serialize(mc: MethodCall, w: SigmaByteWriter): Unit = { - w.put(mc.method.objType.typeId, ArgInfo("typeCode", "type of the method (see Table~\\ref{table:predeftypes})")) - w.put(mc.method.methodId, ArgInfo("methodCode", "a code of the property")) - w.putValue(mc.obj, ArgInfo("obj", "receiver object of this property call")) + w.put(mc.method.objType.typeId, typeCodeInfo) + w.put(mc.method.methodId, methodCodeInfo) + w.putValue(mc.obj, objInfo) } override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ProveDlogSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ProveDlogSerializer.scala index 040461cf48..d94d602c65 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ProveDlogSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ProveDlogSerializer.scala @@ -2,9 +2,10 @@ package sigmastate.serialization import sigmastate.basics.DLogProtocol.ProveDlog import sigmastate.{SGroupElement, CreateProveDlog} -import sigmastate.Values.{Value, SigmaPropValue} +import sigmastate.Values.{Value, SValue, SigmaPropValue} import sigmastate.interpreter.CryptoConstants.EcPointType import sigmastate.lang.Terms._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} case class ProveDlogSerializer(cons: EcPointType => ProveDlog) @@ -23,9 +24,10 @@ case class CreateProveDlogSerializer(cons: Value[SGroupElement.type] => SigmaPro extends ValueSerializer[CreateProveDlog] { import sigmastate.Operations.CreateProveDlogInfo._ override def opDesc = CreateProveDlog + val valueInfo: DataInfo[SValue] = valueArg override def serialize(obj: CreateProveDlog, w: SigmaByteWriter): Unit = { - w.putValue(obj.value, valueArg) + w.putValue(obj.value, valueInfo) } override def parse(r: SigmaByteReader) = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/SelectFieldSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SelectFieldSerializer.scala index 105a84bd6a..6abf691f8d 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/SelectFieldSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/SelectFieldSerializer.scala @@ -1,18 +1,22 @@ package sigmastate.serialization import sigmastate.Operations.SelectFieldInfo -import sigmastate.Values.Value +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.SelectField import sigmastate.{STuple, SType} +import SelectFieldInfo._ +import sigmastate.utils.SigmaByteWriter.DataInfo case class SelectFieldSerializer(cons: (Value[STuple], Byte) => Value[SType]) extends ValueSerializer[SelectField] { override def opDesc = SelectField + val inputInfo: DataInfo[SValue] = inputArg + val fieldIndexInfo: DataInfo[Byte] = fieldIndexArg override def serialize(obj: SelectField, w: SigmaByteWriter): Unit = - w.putValue(obj.input, SelectFieldInfo.inputArg) - .put(obj.fieldIndex, SelectFieldInfo.fieldIndexArg) + w.putValue(obj.input, inputInfo) + .put(obj.fieldIndex, fieldIndexInfo) override def parse(r: SigmaByteReader): Value[SType] = { val tuple = r.getValue().asValue[STuple] diff --git a/sigmastate/src/main/scala/sigmastate/serialization/SigmaPropBytesSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SigmaPropBytesSerializer.scala index e107b6da8a..754880cd16 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/SigmaPropBytesSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/SigmaPropBytesSerializer.scala @@ -1,16 +1,19 @@ package sigmastate.serialization +import sigmastate.Values.SValue import sigmastate.{Values, SType} import sigmastate.lang.Terms._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.SigmaPropBytes object SigmaPropBytesSerializer extends ValueSerializer[SigmaPropBytes] { import sigmastate.Operations.SigmaPropBytesInfo._ override def opDesc = SigmaPropBytes + val thisInfo: DataInfo[SValue] = thisArg def serialize(obj: SigmaPropBytes, w: SigmaByteWriter): Unit = { - w.putValue(obj.input, thisArg) + w.putValue(obj.input, thisInfo) } def parse(r: SigmaByteReader): Values.Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/SubstConstantsSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/SubstConstantsSerializer.scala index 3306ff888d..2c55458280 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/SubstConstantsSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/SubstConstantsSerializer.scala @@ -1,19 +1,23 @@ package sigmastate.serialization -import sigmastate.SCollection.{SByteArray, SIntArray} -import sigmastate.Values.Value +import sigmastate.SCollection.{SIntArray, SByteArray} +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} -import sigmastate.{SCollection, SType, SubstConstants} +import sigmastate.{SCollection, SubstConstants, SType} object SubstConstantsSerializer extends ValueSerializer[SubstConstants[SType]] { import sigmastate.Operations.SubstConstantsInfo._ override def opDesc = SubstConstants + val scriptBytesInfo: DataInfo[SValue] = scriptBytesArg + val positionsInfo: DataInfo[SValue] = positionsArg + val newValuesInfo: DataInfo[SValue] = newValuesArg def serialize(obj: SubstConstants[SType], w: SigmaByteWriter): Unit = { - w.putValue(obj.scriptBytes, scriptBytesArg) - w.putValue(obj.positions, positionsArg) - w.putValue(obj.newValues, newValuesArg) + w.putValue(obj.scriptBytes, scriptBytesInfo) + w.putValue(obj.positions, positionsInfo) + w.putValue(obj.newValues, newValuesInfo) } def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala index 9ea07a2edf..0578f4dc66 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/TupleSerializer.scala @@ -1,19 +1,22 @@ package sigmastate.serialization -import sigmastate.{SType, ArgInfo} +import sigmastate.{ArgInfo, SType} import sigmastate.Values._ import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import ValueSerializer._ +import sigmastate.utils.SigmaByteWriter.{DataInfo, U} case class TupleSerializer(cons: Seq[Value[SType]] => Value[SType]) extends ValueSerializer[Tuple] { override def opDesc = Tuple + val numItemsInfo: DataInfo[U[Byte]] = ArgInfo("numItems", "number of items in the tuple") + val itemInfo: DataInfo[SValue] = ArgInfo("item_i", "tuple's item in i-th position") override def serialize(obj: Tuple, w: SigmaByteWriter): Unit = { val length = obj.length - w.putUByte(length, ArgInfo("numItems", "number of items in the tuple")) - foreach("numItems", obj.items) { i => - w.putValue(i, ArgInfo("item_i", "tuple's item in i-th position")) + w.putUByte(length, numItemsInfo) + foreach(numItemsInfo.info.name, obj.items) { i => + w.putValue(i, itemInfo) } } diff --git a/sigmastate/src/main/scala/sigmastate/serialization/TwoArgumentsSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/TwoArgumentsSerializer.scala index 5e3be8fbdc..a4bb89fa29 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/TwoArgumentsSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/TwoArgumentsSerializer.scala @@ -1,18 +1,21 @@ package sigmastate.serialization -import sigmastate.Values.Value +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.{TwoArgumentsOperation, SType, TwoArgumentOperationCompanion} case class TwoArgumentsSerializer[LIV <: SType, RIV <: SType, OV <: Value[SType]] (override val opDesc: TwoArgumentOperationCompanion, constructor: (Value[LIV], Value[RIV]) => Value[SType]) extends ValueSerializer[OV] { + val leftInfo: DataInfo[SValue] = opDesc.argInfos(0) + val rightInfo: DataInfo[SValue] = opDesc.argInfos(1) override def serialize(obj: OV, w: SigmaByteWriter): Unit = { val typedOp = obj.asInstanceOf[TwoArgumentsOperation[LIV, RIV, LIV]] - w.putValue(typedOp.left, opDesc.argInfos(0)) - .putValue(typedOp.right, opDesc.argInfos(1)) + w.putValue(typedOp.left, leftInfo) + .putValue(typedOp.right, rightInfo) } override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ValDefSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ValDefSerializer.scala index 084e49ec73..8d83ea0b21 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ValDefSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ValDefSerializer.scala @@ -14,10 +14,15 @@ case class ValDefSerializer(override val opDesc: ValueCompanion) extends ValueSe w.putUInt(obj.id) optional("type arguments") { if (opCode == FunDefCode) { + val args = obj.tpeArgs + val len = args.length require(!obj.isValDef, s"expected FunDef, got $obj") - require(obj.tpeArgs.nonEmpty, s"expected FunDef with type args, got $obj") - w.put(obj.tpeArgs.length.toByteExact) - obj.tpeArgs.foreach(w.putType(_)) + require(len > 0, s"expected FunDef with type args, got $obj") + w.put(len.toByteExact) + cfor(0)(_ < len, _ + 1) { i => + val arg = args(i) + w.putType(arg) + } } } w.putValue(obj.rhs) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala index a4766bb882..2b5d8ffc77 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/ValueSerializer.scala @@ -6,7 +6,6 @@ import sigmastate.SCollection.SByteArray import sigmastate.Values._ import sigmastate._ import sigmastate.lang.DeserializationSigmaBuilder -import sigmastate.lang.Terms.OperationId import sigmastate.serialization.OpCodes._ import sigmastate.serialization.transformers._ import sigmastate.serialization.trees.{QuadrupleSerializer, Relation2Serializer} @@ -14,7 +13,6 @@ import scalan.util.Extensions._ import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils._ import sigmastate.utxo.ComplexityTable._ -import sigmastate.utxo.CostTable._ import sigmastate.utxo._ import scala.collection.mutable diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/BooleanTransformerSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/BooleanTransformerSerializer.scala index 55f90d1f84..8c5975cf8a 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/BooleanTransformerSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/BooleanTransformerSerializer.scala @@ -1,19 +1,22 @@ package sigmastate.serialization.transformers -import sigmastate.Values.{Value, ValueCompanion} +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.{BooleanTransformer, BooleanTransformerCompanion} import sigmastate.{SCollection, SBoolean, SType, SFunc} case class BooleanTransformerSerializer[T <: SType] -(opDesc: BooleanTransformerCompanion, - f: (Value[SCollection[T]], Value[SFunc]) => Value[SBoolean.type]) extends ValueSerializer[BooleanTransformer[T]] { + (opDesc: BooleanTransformerCompanion, + f: (Value[SCollection[T]], Value[SFunc]) => Value[SBoolean.type]) extends ValueSerializer[BooleanTransformer[T]] { + val inputInfo: DataInfo[SValue] = opDesc.argInfos(0) + val conditionInfo: DataInfo[SValue] = opDesc.argInfos(1) override def serialize(obj: BooleanTransformer[T], w: SigmaByteWriter): Unit = - w.putValue(obj.input, opDesc.argInfos(0)) - .putValue(obj.condition, opDesc.argInfos(1)) + w.putValue(obj.input, inputInfo) + .putValue(obj.condition, conditionInfo) override def parse(r: SigmaByteReader): Value[SBoolean.type] = { val input = r.getValue().asCollection[T] diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/ByIndexSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/ByIndexSerializer.scala index fe553bdf16..15ea23db30 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/ByIndexSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/ByIndexSerializer.scala @@ -1,10 +1,11 @@ package sigmastate.serialization.transformers -import sigmastate.Values.Value +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer import ValueSerializer._ import sigmastate.Operations.ByIndexInfo._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.ByIndex import sigmastate.{SInt, SCollection, SType} @@ -12,11 +13,14 @@ import sigmastate.{SInt, SCollection, SType} case class ByIndexSerializer(cons: (Value[SCollection[SType]], Value[SInt.type], Option[Value[SType]]) => Value[SType]) extends ValueSerializer[ByIndex[SType]] { override def opDesc = ByIndex + val inputInfo: DataInfo[SValue] = thisArg + val indexInfo: DataInfo[SValue] = indexArg + val defaultInfo: DataInfo[SValue] = defaultArg override def serialize(obj: ByIndex[SType], w: SigmaByteWriter): Unit = { - w.putValue(obj.input, thisArg) - .putValue(obj.index, indexArg) - opt(w, "default", obj.default)(_.putValue(_, defaultArg)) + w.putValue(obj.input, inputInfo) + .putValue(obj.index, indexInfo) + opt(w, "default", obj.default)(_.putValue(_, defaultInfo)) } override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeContextSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeContextSerializer.scala index 5f83555405..e172028221 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeContextSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeContextSerializer.scala @@ -11,10 +11,12 @@ import sigmastate.Operations.DeserializeContextInfo case class DeserializeContextSerializer(cons: (Byte, SType) => Value[SType]) extends ValueSerializer[DeserializeContext[SType]] { override def opDesc = DeserializeContext + val typeInfo: DataInfo[SType] = ArgInfo("type", "expected type of the deserialized script") + val idInfo: DataInfo[Byte] = DeserializeContextInfo.idArg override def serialize(obj: DeserializeContext[SType], w: SigmaByteWriter): Unit = - w.putType(obj.tpe, ArgInfo("type", "expected type of the deserialized script")) - .put(obj.id, DeserializeContextInfo.idArg) + w.putType(obj.tpe, typeInfo) + .put(obj.id, idInfo) override def parse(r: SigmaByteReader): Value[SType] = { val tpe = r.getType() diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeRegisterSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeRegisterSerializer.scala index 0de85c256d..9925d3eeed 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeRegisterSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/DeserializeRegisterSerializer.scala @@ -2,24 +2,28 @@ package sigmastate.serialization.transformers import org.ergoplatform.ErgoBox import org.ergoplatform.ErgoBox.RegisterId -import sigmastate.Operations.DeserializeRegisterInfo import sigmastate.{ArgInfo, SType} -import sigmastate.Values.Value +import sigmastate.Values.{Value, SValue} import sigmastate.serialization.ValueSerializer import ValueSerializer._ import sigmastate.Operations.DeserializeRegisterInfo._ +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.DeserializeRegister case class DeserializeRegisterSerializer(cons: (RegisterId, SType, Option[Value[SType]]) => Value[SType]) extends ValueSerializer[DeserializeRegister[SType]] { override def opDesc = DeserializeRegister + val idInfo: DataInfo[Byte] = idArg + val typeInfo: DataInfo[SType] = ArgInfo("type", "expected type of the deserialized script") + val defaultInfo: DataInfo[SValue] = defaultArg override def serialize(obj: DeserializeRegister[SType], w: SigmaByteWriter): Unit = { - w.put(obj.reg.number, idArg) - w.putType(obj.tpe, ArgInfo("type", "expected type of the deserialized script")) - opt(w, "default", obj.default)(_.putValue(_, defaultArg)) + w.put(obj.reg.number, idInfo) + w.putType(obj.tpe, typeInfo) + opt(w, "default", obj.default)(_.putValue(_, defaultInfo)) } + override def parse(r: SigmaByteReader): Value[SType] = { val registerId = ErgoBox.findRegisterByIndex(r.getByte()).get val tpe = r.getType() diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/ExtractRegisterAsSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/ExtractRegisterAsSerializer.scala index cef8c2b694..f84933b332 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/ExtractRegisterAsSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/ExtractRegisterAsSerializer.scala @@ -2,21 +2,25 @@ package sigmastate.serialization.transformers import org.ergoplatform.ErgoBox import org.ergoplatform.ErgoBox.RegisterId -import sigmastate.Values.Value +import sigmastate.Values.{Value, SValue} import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.ExtractRegisterAs -import sigmastate.{SBox, SOption, SType, ArgInfo} +import sigmastate.{SBox, SOption, ArgInfo, SType} case class ExtractRegisterAsSerializer(cons: (Value[SBox.type], RegisterId, SOption[SType]) => Value[SType]) extends ValueSerializer[ExtractRegisterAs[SType]] { import sigmastate.Operations.ExtractRegisterAsInfo._ override def opDesc = ExtractRegisterAs + val thisInfo: DataInfo[SValue] = thisArg + val regIdInfo: DataInfo[Byte] = regIdArg + val typeInfo: DataInfo[SType] = ArgInfo("type", "expected type of the value in register") override def serialize(obj: ExtractRegisterAs[SType], w: SigmaByteWriter): Unit = - w.putValue(obj.input, thisArg) - .put(obj.registerId.number, regIdArg) - .putType(obj.tpe.elemType, ArgInfo("type", "expected type of the value in register")) + w.putValue(obj.input, thisInfo) + .put(obj.registerId.number, regIdInfo) + .putType(obj.tpe.elemType, typeInfo) override def parse(r: SigmaByteReader): Value[SType] = { val input = r.getValue() diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/FoldSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/FoldSerializer.scala index 42e72acf43..0159e10a0a 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/FoldSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/FoldSerializer.scala @@ -1,8 +1,9 @@ package sigmastate.serialization.transformers -import sigmastate.Values.Value +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.Fold import sigmastate.{SCollection, SType, SFunc} @@ -10,12 +11,15 @@ import sigmastate.{SCollection, SType, SFunc} case class FoldSerializer(cons: (Value[SCollection[SType]], Value[SType], Value[SFunc]) => Value[SType]) extends ValueSerializer[Fold[SType, SType]] { override def opDesc = Fold + import sigmastate.Operations.FoldInfo._ + val thisInfo: DataInfo[SValue] = thisArg + val zeroInfo: DataInfo[SValue] = zeroArg + val opInfo: DataInfo[SValue] = opArg override def serialize(obj: Fold[SType, SType], w: SigmaByteWriter): Unit = { - import sigmastate.Operations.FoldInfo._ - w.putValue(obj.input, thisArg) - .putValue(obj.zero, zeroArg) - .putValue(obj.foldOp, opArg) + w.putValue(obj.input, thisInfo) + .putValue(obj.zero, zeroInfo) + .putValue(obj.foldOp, opInfo) } override def parse(r: SigmaByteReader): Value[SType] = { diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/MapCollectionSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/MapCollectionSerializer.scala index 6d149c3749..3e6fab5949 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/MapCollectionSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/MapCollectionSerializer.scala @@ -1,8 +1,9 @@ package sigmastate.serialization.transformers -import sigmastate.Values.Value +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.MapCollection import sigmastate.{SCollection, SType, SFunc} @@ -11,10 +12,12 @@ case class MapCollectionSerializer(cons: (Value[SCollection[SType]], Value[SFunc extends ValueSerializer[MapCollection[SType, SType]] { import sigmastate.Operations.MapCollectionInfo._ override def opDesc = MapCollection + val thisInfo: DataInfo[SValue] = thisArg + val fInfo: DataInfo[SValue] = fArg override def serialize(obj: MapCollection[SType, SType], w: SigmaByteWriter): Unit = - w.putValue(obj.input, thisArg) - .putValue(obj.mapper, fArg) + w.putValue(obj.input, thisInfo) + .putValue(obj.mapper, fInfo) override def parse(r: SigmaByteReader): Value[SType] = { val input = r.getValue().asValue[SCollection[SType]] diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/NumericCastSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/NumericCastSerializer.scala index d939718cd2..88d521ae09 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/NumericCastSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/NumericCastSerializer.scala @@ -1,19 +1,22 @@ package sigmastate.serialization.transformers -import sigmastate.Values.{Value, ValueCompanion} +import sigmastate.Values.{Value, SValue} import sigmastate._ import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.Transformer case class NumericCastSerializer(opDesc: NumericCastCompanion, cons: (Value[SNumericType], SNumericType) => Value[SNumericType]) extends ValueSerializer[Transformer[SNumericType, SNumericType]] { + val inputInfo: DataInfo[SValue] = opDesc.argInfos(0) + val typeInfo: DataInfo[SType] = ArgInfo("type", "resulting type of the cast operation") override def serialize(obj: Transformer[SNumericType, SNumericType], w: SigmaByteWriter): Unit = - w.putValue(obj.input, opDesc.argInfos(0)) - .putType(obj.tpe, ArgInfo("type", "resulting type of the cast operation")) + w.putValue(obj.input, inputInfo) + .putType(obj.tpe, typeInfo) override def parse(r: SigmaByteReader): Value[SNumericType] = { val input = r.getValue().asNumValue diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/SigmaTransformerSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/SigmaTransformerSerializer.scala index d736826d29..ab195146af 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/SigmaTransformerSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/SigmaTransformerSerializer.scala @@ -1,25 +1,27 @@ package sigmastate.serialization.transformers -import sigmastate.{SigmaTransformer, SigmaTransformerCompanion} -import sigmastate.Values.{ValueCompanion, SigmaPropValue} +import sigmastate.{SigmaTransformerCompanion, SigmaTransformer} +import sigmastate.Values.{SigmaPropValue, SValue} import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.{DataInfo, valuesItemInfo} import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} - -import scala.collection.mutable +import spire.syntax.all.cfor case class SigmaTransformerSerializer[I <: SigmaPropValue, O <: SigmaPropValue] (opDesc: SigmaTransformerCompanion, cons: Seq[SigmaPropValue] => SigmaPropValue) extends ValueSerializer[SigmaTransformer[I, O]] { + val itemsInfo: DataInfo[Seq[SValue]] = opDesc.argInfos(0) + val itemsItemInfo = valuesItemInfo(itemsInfo) override def serialize(obj: SigmaTransformer[I, O], w: SigmaByteWriter): Unit = - w.putValues(obj.items, opDesc.argInfos(0)) + w.putValues(obj.items, itemsInfo, itemsItemInfo) override def parse(r: SigmaByteReader): SigmaPropValue = { val itemsSize = r.getUInt().toInt - val b = mutable.ArrayBuilder.make[SigmaPropValue]() - for (_ <- 0 until itemsSize) { - b += r.getValue().asInstanceOf[SigmaPropValue] + val res = new Array[SigmaPropValue](itemsSize) + cfor(0)(_ < itemsSize, _ + 1) { i => + res(i) = r.getValue().asInstanceOf[SigmaPropValue] } - cons(b.result()) + cons(res) } } diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/SimpleTransformerSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/SimpleTransformerSerializer.scala index 68b8c9a602..f01ae8fd20 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/SimpleTransformerSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/SimpleTransformerSerializer.scala @@ -1,18 +1,20 @@ package sigmastate.serialization.transformers import sigmastate.SType -import sigmastate.Values.{Value, ValueCompanion} +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.{Transformer, SimpleTransformerCompanion} case class SimpleTransformerSerializer[I <: SType, O <: SType] (opDesc: SimpleTransformerCompanion, cons: Value[I] => Value[O]) extends ValueSerializer[Transformer[I, O]] { - + val inputInfo: DataInfo[SValue] = opDesc.argInfos(0) + override def serialize(obj: Transformer[I, O], w: SigmaByteWriter): Unit = - w.putValue(obj.input, opDesc.argInfos(0)) + w.putValue(obj.input, inputInfo) override def parse(r: SigmaByteReader): Value[O] = cons(r.getValue().asValue[I]) diff --git a/sigmastate/src/main/scala/sigmastate/serialization/transformers/SliceSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/transformers/SliceSerializer.scala index 4a9841fb83..ed4f2a15b7 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/transformers/SliceSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/transformers/SliceSerializer.scala @@ -1,10 +1,9 @@ package sigmastate.serialization.transformers -import sigmastate.Values.Value +import sigmastate.Values.{Value, SValue} import sigmastate.lang.Terms._ -import sigmastate.serialization.OpCodes.OpCode -import sigmastate.serialization.{OpCodes, ValueSerializer} import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.utxo.Slice import sigmastate.{SInt, SCollection, SType} @@ -13,11 +12,14 @@ case class SliceSerializer(cons: (Value[SCollection[SType]], Value[SInt.type], V extends ValueSerializer[Slice[SType]] { import sigmastate.Operations.SliceInfo._ override def opDesc = Slice + val thisInfo: DataInfo[SValue] = thisArg + val fromInfo: DataInfo[SValue] = fromArg + val untilInfo: DataInfo[SValue] = untilArg override def serialize(obj: Slice[SType], w: SigmaByteWriter): Unit = - w.putValue(obj.input, thisArg) - .putValue(obj.from, fromArg) - .putValue(obj.until, untilArg) + w.putValue(obj.input, thisInfo) + .putValue(obj.from, fromInfo) + .putValue(obj.until, untilInfo) override def parse(r: SigmaByteReader): Value[SCollection[SType]] = { val input = r.getValue().asCollection[SType] diff --git a/sigmastate/src/main/scala/sigmastate/serialization/trees/QuadrupleSerializer.scala b/sigmastate/src/main/scala/sigmastate/serialization/trees/QuadrupleSerializer.scala index 859118282b..f6d3f91ff1 100644 --- a/sigmastate/src/main/scala/sigmastate/serialization/trees/QuadrupleSerializer.scala +++ b/sigmastate/src/main/scala/sigmastate/serialization/trees/QuadrupleSerializer.scala @@ -3,6 +3,7 @@ package sigmastate.serialization.trees import sigmastate.Values._ import sigmastate.lang.Terms._ import sigmastate.serialization.ValueSerializer +import sigmastate.utils.SigmaByteWriter.DataInfo import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} import sigmastate.{Quadruple, _} @@ -10,11 +11,14 @@ case class QuadrupleSerializer[S1 <: SType, S2 <: SType, S3 <: SType, S4 <: STyp (override val opDesc: QuadrupleCompanion, cons: (Value[S1], Value[S2], Value[S3]) => Value[S4]) extends ValueSerializer[Quadruple[S1, S2, S3, S4]] { + val firstInfo: DataInfo[SValue] = opDesc.argInfos(0) + val secondInfo: DataInfo[SValue] = opDesc.argInfos(1) + val thirdInfo: DataInfo[SValue] = opDesc.argInfos(2) override def serialize(obj: Quadruple[S1, S2, S3, S4], w: SigmaByteWriter): Unit = { - w.putValue(obj.first, opDesc.argInfos(0)) - w.putValue(obj.second, opDesc.argInfos(1)) - w.putValue(obj.third, opDesc.argInfos(2)) + w.putValue(obj.first, firstInfo) + w.putValue(obj.second, secondInfo) + w.putValue(obj.third, thirdInfo) } override def parse(r: SigmaByteReader): Value[S4] = { diff --git a/sigmastate/src/main/scala/sigmastate/utils/SigmaByteWriter.scala b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteWriter.scala index 43d05e8407..c5b34010af 100644 --- a/sigmastate/src/main/scala/sigmastate/utils/SigmaByteWriter.scala +++ b/sigmastate/src/main/scala/sigmastate/utils/SigmaByteWriter.scala @@ -119,11 +119,10 @@ class SigmaByteWriter(val w: Writer, xs.foreach(putValue(_)) this } - @inline def putValues[T <: SType](xs: Seq[Value[T]], info: DataInfo[Seq[SValue]]): this.type = { - putUInt(xs.length, ArgInfo("\\#items", "number of items in the collection")) + @inline def putValues[T <: SType](xs: Seq[Value[T]], info: DataInfo[Seq[SValue]], itemInfo: DataInfo[SValue]): this.type = { + putUInt(xs.length, valuesLengthInfo) foreach("\\#items", xs) { x => - val itemFmt = info.format.asInstanceOf[SeqFmt[SValue]].fmt - putValue(x, DataInfo(ArgInfo(info.info.name+"_i", s"i-th item in the ${info.info.description}"), itemFmt)) + putValue(x, itemInfo) } this } @@ -246,6 +245,13 @@ object SigmaByteWriter { def bitsInfo(name: String, desc: String = ""): DataInfo[Bits] = DataInfo(ArgInfo(name, desc), BitsFmt) def maxBitsInfo(name: String, maxBits: Int, desc: String = ""): DataInfo[Bits] = DataInfo(ArgInfo(name, desc), MaxBitsFmt(maxBits)) + val valuesLengthInfo: DataInfo[Vlq[U[Int]]] = ArgInfo("\\#items", "number of items in the collection") + + def valuesItemInfo(info: DataInfo[Seq[SValue]]): DataInfo[SValue] = { + val itemFmt = info.format.asInstanceOf[SeqFmt[SValue]].fmt + DataInfo(ArgInfo(info.info.name+"_i", s"i-th item in the ${info.info.description}"), itemFmt) + } + implicit def argInfoToDataInfo[T](arg: ArgInfo)(implicit fmt: FormatDescriptor[T]): DataInfo[T] = DataInfo(arg, fmt) // TODO remove this conversion and make it explicit From cf023983ee630ddec5f576c08cb6c066f961b666 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 30 Oct 2019 14:24:11 +0300 Subject: [PATCH 12/16] use WrappedArray as representation of Seq --- sigmastate/src/main/scala/sigmastate/Values.scala | 5 ++++- .../main/scala/sigmastate/eval/TreeBuilding.scala | 4 ++-- .../main/scala/sigmastate/lang/SigmaTyper.scala | 14 +++++++------- .../main/scala/sigmastate/lang/syntax/Exprs.scala | 11 ++++++----- sigmastate/src/main/scala/sigmastate/trees.scala | 8 +++++--- .../org/ergoplatform/ErgoScriptPredefSpec.scala | 2 +- .../sigmastate/eval/ErgoTreeBuildingTest.scala | 14 +++++++------- .../scala/sigmastate/eval/EvaluationTest.scala | 2 +- .../scala/sigmastate/lang/SigmaBinderTest.scala | 6 +++--- .../scala/sigmastate/lang/SigmaCompilerTest.scala | 2 +- .../sigmastate/lang/SigmaSpecializerTest.scala | 8 ++++---- ...ConcreteCollectionSerializerSpecification.scala | 2 +- .../serialization/DeserializationResilience.scala | 2 +- .../generators/ObjectGenerators.scala | 2 +- .../sigmastate/utxo/BasicOpsSpecification.scala | 10 +++++----- .../utxo/CollectionOperationsSpecification.scala | 14 +++++++------- .../sigmastate/utxo/ThresholdSpecification.scala | 4 ++-- .../examples/AtomicSwapExampleSpecification.scala | 2 +- .../utxo/examples/Rule110Specification.scala | 6 +++--- 19 files changed, 62 insertions(+), 56 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index 8344ce73a3..fb58e685b4 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -13,7 +13,7 @@ import scorex.crypto.authds.{ADDigest, SerializedAdProof} import scorex.crypto.authds.avltree.batch.BatchAVLVerifier import scorex.crypto.hash.{Digest32, Blake2b256} import scalan.util.CollectionUtil._ -import sigmastate.SCollection.{SByteArray, SIntArray} +import sigmastate.SCollection.{SIntArray, SByteArray} import sigmastate.interpreter.CryptoConstants.EcPointType import sigmastate.interpreter.CryptoConstants import sigmastate.serialization.{OpCodes, ConstantStore, _} @@ -669,6 +669,9 @@ object Values { case class ConcreteCollection[V <: SType](items: Seq[Value[V]], elementType: V) extends EvaluatedCollection[V, SCollection[V]] { +// TODO uncomment and make sure Ergo works with it, i.e. complex data types are never used for `items` +// assert(items.isInstanceOf[mutable.WrappedArray[_]] || items.isInstanceOf[mutable.IndexedSeq[_]], +// s"Invalid types of items ${items.getClass}") private val isBooleanConstants = elementType == SBoolean && items.forall(_.isInstanceOf[Constant[_]]) override def companion = if (isBooleanConstants) ConcreteCollectionBooleanConstant diff --git a/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala index 71c0f32fed..8e661be19b 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/TreeBuilding.scala @@ -138,7 +138,7 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => rhs case Def(Apply(fSym, xSym, _)) => val Seq(f, x) = Seq(fSym, xSym).map(recurse) - builder.mkApply(f, IndexedSeq(x)) + builder.mkApply(f, Array(x)) case Def(th @ ThunkDef(root, _)) => val block = processAstGraph(ctx, mainG, env, th, defId, constantsProcessing) block @@ -177,7 +177,7 @@ trait TreeBuilding extends RuntimeCosting { IR: IRContext => case CBM.fromItems(_, colSyms, elemT) => val elemTpe = elemToSType(elemT) val col = colSyms.map(recurse(_).asValue[elemTpe.type]) - mkConcreteCollection[elemTpe.type](col.toIndexedSeq, elemTpe) + mkConcreteCollection[elemTpe.type](col.toArray[Value[elemTpe.type]], elemTpe) case CBM.xor(_, colSym1, colSym2) => mkXor(recurse(colSym1), recurse(colSym2)) diff --git a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala index 58906d08a4..93adb756c5 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/SigmaTyper.scala @@ -146,7 +146,7 @@ class SigmaTyper(val builder: SigmaBuilder, predefFuncRegistry: PredefinedFuncRe .getOrElse(mkMethodCall(newObj, method, newArgs, subst)) } else { val newSelect = mkSelect(newObj, n, Some(concrFunTpe)).withSrcCtx(sel.sourceContext) - mkApply(newSelect, newArgs) + mkApply(newSelect, newArgs.toArray[SValue]) } case Some(method) => error(s"Don't know how to handle method $method in obj $p", sel.sourceContext) @@ -179,13 +179,13 @@ class SigmaTyper(val builder: SigmaBuilder, predefFuncRegistry: PredefinedFuncRe .getOrElse(mkMethodCall(newObj, methodConcrType, newArgs, Map())) case _ => val newSelect = mkSelect(newObj, n, Some(concrFunTpe)).withSrcCtx(sel.sourceContext) - mkApply(newSelect, newArgs) + mkApply(newSelect, newArgs.toArray[SValue]) } case None => error(s"Invalid argument type of application $app: expected $argTypes; actual: $newArgTypes", sel.sourceContext) } case _ => - mkApply(newSel, newArgs) + mkApply(newSel, newArgs.toArray[SValue]) } case a @ Apply(ident: Ident, args) if SGlobal.hasMethod(ident.name) => // example: groupGenerator() @@ -215,7 +215,7 @@ class SigmaTyper(val builder: SigmaBuilder, predefFuncRegistry: PredefinedFuncRe val actualTypes = adaptedTypedArgs.map(_.tpe) unifyTypeLists(argTypes, actualTypes) match { case Some(_) => - mkApply(new_f, adaptedTypedArgs.toIndexedSeq) + mkApply(new_f, adaptedTypedArgs.toArray[SValue]) case None => error(s"Invalid argument type of application $app: expected $argTypes; actual after typing: $actualTypes", app.sourceContext) } @@ -526,12 +526,12 @@ class SigmaTyper(val builder: SigmaBuilder, predefFuncRegistry: PredefinedFuncRe def adaptSigmaPropToBoolean(items: Seq[Value[SType]], expectedTypes: Seq[SType]): Seq[Value[SType]] = { val res = items.zip(expectedTypes).map { case (cc: ConcreteCollection[SType]@unchecked, SBooleanArray) => - val items = adaptSigmaPropToBoolean(cc.items, Seq.fill(cc.items.length)(SBoolean)) - assignConcreteCollection(cc, items.toIndexedSeq) + val items = adaptSigmaPropToBoolean(cc.items, Array.fill(cc.items.length)(SBoolean)) + assignConcreteCollection(cc, items) case (it, SBoolean) if it.tpe == SSigmaProp => SigmaPropIsProven(it.asSigmaProp) case (it,_) => it } - res + res.toArray[SValue] } def bimap[T <: SType] diff --git a/sigmastate/src/main/scala/sigmastate/lang/syntax/Exprs.scala b/sigmastate/src/main/scala/sigmastate/lang/syntax/Exprs.scala index 1fae7a1481..56e50b9546 100644 --- a/sigmastate/src/main/scala/sigmastate/lang/syntax/Exprs.scala +++ b/sigmastate/src/main/scala/sigmastate/lang/syntax/Exprs.scala @@ -4,12 +4,13 @@ import fastparse.noApi._ import scalan.Nullable import sigmastate._ import sigmastate.Values._ -import sigmastate.lang.Terms.{Ident, Val, ValueOps} +import sigmastate.lang.Terms.{ValueOps, Ident, Val} import sigmastate.lang._ import sigmastate.lang.SigmaPredef._ import sigmastate.lang.syntax.Basic._ import scala.annotation.tailrec +import scala.collection.mutable //noinspection ForwardReference,TypeAnnotation trait Exprs extends Core with Types { @@ -185,17 +186,17 @@ trait Exprs extends Core with Types { builder.currentSrcCtx.withValue(f.sourceContext) { val rhs = args.foldLeft(f)((acc, arg) => arg match { case Ident(name, _) => mkSelect(acc, name) - case UnitConstant() => mkApply(acc, IndexedSeq.empty) - case Tuple(xs) => mkApply(acc, xs) + case UnitConstant() => mkApply(acc, mutable.WrappedArray.empty) + case Tuple(xs) => mkApply(acc, xs.toArray[SValue]) case STypeApply("", targs) => mkApplyTypes(acc, targs) case arg: SValue => acc match { case Ident(name, _) if name == ZKProofFunc.name => arg match { case Terms.Block(_, body) => - mkApply(mkIdent(ZKProofFunc.name, ZKProofFunc.declaration.tpe), IndexedSeq(body)) + mkApply(mkIdent(ZKProofFunc.name, ZKProofFunc.declaration.tpe), Array(body)) case nonBlock => error(s"expected block parameter for ZKProof, got $nonBlock", nonBlock.sourceContext) } - case _ => mkApply(acc, IndexedSeq(arg)) + case _ => mkApply(acc, Array(arg)) } case _ => error(s"Error after expression $f: invalid suffixes $args", f.sourceContext) }) diff --git a/sigmastate/src/main/scala/sigmastate/trees.scala b/sigmastate/src/main/scala/sigmastate/trees.scala index a6b4fa0710..3d30dd2fe2 100644 --- a/sigmastate/src/main/scala/sigmastate/trees.scala +++ b/sigmastate/src/main/scala/sigmastate/trees.scala @@ -2,12 +2,13 @@ package sigmastate import org.ergoplatform.SigmaConstants import org.ergoplatform.validation.SigmaValidationSettings +import scalan.OverloadHack.Overloaded1 import scorex.crypto.hash.{Sha256, Blake2b256, CryptographicHash32} import sigmastate.Operations._ import sigmastate.SCollection.{SIntArray, SByteArray} import sigmastate.SOption.SIntOption import sigmastate.Values._ -import sigmastate.basics.{SigmaProtocol, SigmaProtocolCommonInput, SigmaProtocolPrivateInput} +import sigmastate.basics.{SigmaProtocol, SigmaProtocolPrivateInput, SigmaProtocolCommonInput} import sigmastate.serialization.OpCodes._ import sigmastate.serialization._ import sigmastate.utxo.{Transformer, SimpleTransformerCompanion} @@ -208,7 +209,7 @@ object OR extends LogicalTransformerCompanion { def apply(children: Seq[Value[SBoolean.type]]): OR = OR(ConcreteCollection.fromSeq(children)) - def apply(head: Value[SBoolean.type], tail: Value[SBoolean.type]*): OR = apply(head +: tail) + def apply(items: Value[SBoolean.type]*)(implicit o: Overloaded1): OR = apply(items) } /** Similar to allOf, but performing logical XOR operation instead of `&&` @@ -250,7 +251,8 @@ 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(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/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala index c3cb355024..a64b814e49 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala @@ -68,7 +68,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { def R4Prop(ableToProve: Boolean): CollectionConstant[SByte.type] = if (ableToProve) { val pks = (DLogProverInput.random() +: prover.dlogSecrets.take(2)).map(s => SigmaPropConstant(s.publicImage)) - ByteArrayConstant(ValueSerializer.serialize(AtLeast(IntConstant(2), pks))) + ByteArrayConstant(ValueSerializer.serialize(AtLeast(IntConstant(2), pks.toArray))) } else { val pk = (new ContextEnrichingTestProvingInterpreter).dlogSecrets.head.publicImage ByteArrayConstant(ValueSerializer.serialize(SigmaPropConstant(pk))) diff --git a/sigmastate/src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala b/sigmastate/src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala index 40859c0d90..1d35ed2336 100644 --- a/sigmastate/src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/ErgoTreeBuildingTest.scala @@ -94,14 +94,14 @@ class ErgoTreeBuildingTest extends BaseCtxTests val projectPK = prover.dlogSecrets(1).publicImage val env = envCF ++ Seq("projectPubKey" -> projectPK, "backerPubKey" -> backerPK) build(env, "CrowdFunding", crowdFundingScript, - BlockValue(Vector( - ValDef(1,List(),SigmaPropConstant(projectPK))), - SigmaOr(Seq( - SigmaAnd(Seq(BoolToSigmaProp(GE(Height,IntConstant(100))),SigmaPropConstant(backerPK))), - SigmaAnd(Seq( - BoolToSigmaProp(AND(Vector( + BlockValue(Array( + ValDef(1,Nil,SigmaPropConstant(projectPK))), + SigmaOr(Array( + SigmaAnd(Array(BoolToSigmaProp(GE(Height,IntConstant(100))),SigmaPropConstant(backerPK))), + SigmaAnd(Array( + BoolToSigmaProp(AND(Array( LT(Height,IntConstant(100)), - Exists(Outputs, FuncValue(Vector((2,SBox)), + Exists(Outputs, FuncValue(Array((2,SBox)), BinAnd( GE(ExtractAmount(ValUse(2,SBox)),LongConstant(1000)), EQ(ExtractScriptBytes(ValUse(2,SBox)), SigmaPropBytes(ValUse(1,SSigmaProp))))) diff --git a/sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala b/sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala index 7d94fbea84..32ff2d3d29 100644 --- a/sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala +++ b/sigmastate/src/test/scala/sigmastate/eval/EvaluationTest.scala @@ -106,7 +106,7 @@ class EvaluationTest extends BaseCtxTests val inputBytes = DefaultSerializer.serializeErgoTree(script1.treeWithSegregation) val positions = IntArrayConstant(Array[Int](2)) // in ergo we have only byte array of a serialized group element - val newVals = ConcreteCollection(Vector[SigmaPropValue](CreateProveDlog(DecodePoint(pk2.pkBytes))), SSigmaProp) + val newVals = ConcreteCollection(Array[SigmaPropValue](CreateProveDlog(DecodePoint(pk2.pkBytes))), SSigmaProp) val expectedBytes = DefaultSerializer.serializeErgoTree(script2.treeWithSegregation) val ctx = newErgoContext(height = 1, boxToSpend) diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala index e5a2eb5da1..5b7bfbd303 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaBinderTest.scala @@ -122,10 +122,10 @@ class SigmaBinderTest extends PropSpec with PropertyChecks with Matchers with La bind(env, "{val X: (Int, Boolean) = (10, true); 3 > 2}") shouldBe Block(Val("X", STuple(SInt, SBoolean), Tuple(IntConstant(10), TrueLeaf)), GT(3, 2)) bind(env, "{val X: Coll[Int] = Coll(1,2,3); X.size}") shouldBe - Block(Val("X", SCollection(SInt), ConcreteCollection.fromSeq(Seq(IntConstant(1), IntConstant(2), IntConstant(3)))), + Block(Val("X", SCollection(SInt), ConcreteCollection.fromSeq(Array(IntConstant(1), IntConstant(2), IntConstant(3)))), Select(Ident("X"), "size")) bind(env, "{val X: (Coll[Int], Box) = (Coll(1,2,3), INPUT); X._1}") shouldBe - Block(Val("X", STuple(SCollection(SInt), SBox), Tuple(ConcreteCollection.fromSeq(Seq(IntConstant(1), IntConstant(2), IntConstant(3))), Ident("INPUT"))), + Block(Val("X", STuple(SCollection(SInt), SBox), Tuple(ConcreteCollection.fromSeq(Array(IntConstant(1), IntConstant(2), IntConstant(3))), Ident("INPUT"))), Select(Ident("X"), "_1")) } @@ -191,7 +191,7 @@ class SigmaBinderTest extends PropSpec with PropertyChecks with Matchers with La bind(env, "f[Int](10)") shouldBe Apply(ApplyTypes(Ident("f"), Seq(SInt)), IndexedSeq(IntConstant(10))) bind(env, "INPUTS.map[Int]") shouldBe ApplyTypes(Select(Inputs, "map"), Seq(SInt)) bind(env, "INPUTS.map[Int](10)") shouldBe Apply(ApplyTypes(Select(Inputs, "map"), Seq(SInt)), IndexedSeq(IntConstant(10))) - bind(env, "Coll[Int]()") shouldBe ConcreteCollection.fromItems()(SInt) + bind(env, "Coll[Int]()") shouldBe ConcreteCollection.fromSeq(Array[SValue]())(SInt) } property("val fails (already defined in env)") { diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala index a4f1ecc3dc..a9dba2bafb 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaCompilerTest.scala @@ -538,7 +538,7 @@ class SigmaCompilerTest extends SigmaTestingCommons with LangTests with ObjectGe } property("xorOf") { - comp("xorOf(Coll[Boolean](true, false))") shouldBe XorOf(Seq(TrueLeaf, FalseLeaf)) + comp("xorOf(Coll[Boolean](true, false))") shouldBe XorOf(Array(TrueLeaf, FalseLeaf)) } property("substConst") { diff --git a/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala b/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala index 0676afcc8f..a2ceefd828 100644 --- a/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala +++ b/sigmastate/src/test/scala/sigmastate/lang/SigmaSpecializerTest.scala @@ -132,9 +132,9 @@ class SigmaSpecializerTest extends PropSpec } property("AND flattening, CAND/COR untouched") { - val sigmaBooleans1 = AND(Seq(TrueLeaf, CAND(Seq(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven)) + val sigmaBooleans1 = AND(Array(TrueLeaf, CAND(Array(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven)) spec(Map(), sigmaBooleans1) shouldBe sigmaBooleans1 - val sigmaBooleans2 = AND(Seq(TrueLeaf, COR(Seq(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven)) + val sigmaBooleans2 = AND(Array(TrueLeaf, COR(Array(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven)) spec(Map(), sigmaBooleans2) shouldBe sigmaBooleans2 } @@ -159,9 +159,9 @@ class SigmaSpecializerTest extends PropSpec } property("OR flattening, CAND/COR untouched") { - val sigmaBooleans1 = OR(Seq(TrueLeaf, CAND(Seq(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven)) + val sigmaBooleans1 = OR(Array(TrueLeaf, CAND(Array(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven)) spec(Map(), sigmaBooleans1) shouldBe sigmaBooleans1 - val sigmaBooleans2 = OR(Seq(TrueLeaf, COR(Seq(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven)) + val sigmaBooleans2 = OR(Array(TrueLeaf, COR(Array(proveDlogGen.sample.get, proveDHTGen.sample.get)).toSigmaProp.isProven)) spec(Map(), sigmaBooleans2) shouldBe sigmaBooleans2 } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala b/sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala index 08547d0688..a0812597e5 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/ConcreteCollectionSerializerSpecification.scala @@ -38,7 +38,7 @@ class ConcreteCollectionSerializerSpecification extends TableSerializationSpecif property("ConcreteCollection: Serializer round trip with different types seq") { forAll { (i: IntConstant, ti: TaggedInt) => - val seq = Random.shuffle(Seq(i.asIntValue, ti.asIntValue)) + val seq = Random.shuffle(Seq(i.asIntValue, ti.asIntValue)).toArray roundTripTest(ConcreteCollection.fromSeq(seq)) } } diff --git a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala index 4f6f6be3a5..04811c5f31 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala @@ -88,7 +88,7 @@ class DeserializationResilience extends SerializationSpecification with SigmaTes // guard should not be tripped up by a huge collection val goodBytes = SigmaSerializer.startWriter() - .putValue(AND(List.tabulate(SigmaSerializer.MaxTreeDepth + 1)(_ => booleanExprGen.sample.get))) + .putValue(AND(Array.tabulate(SigmaSerializer.MaxTreeDepth + 1)(_ => booleanExprGen.sample.get))) .toBytes ValueSerializer.deserialize(goodBytes, 0) // test other API endpoints diff --git a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index a67374a0ad..6407db9f64 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -506,7 +506,7 @@ trait ObjectGenerators extends TypeGenerators with ValidationSpecification with def logicalExprTreeNodeGen(nodeCons: Seq[LogicalTransformerCons]): Gen[Transformer[SCollection[SBoolean.type], SBoolean.type]] = for { left <- logicalExprTreeGen(nodeCons) right <- logicalExprTreeGen(nodeCons) - node <- Gen.oneOf(nodeCons.map(cons => cons(Seq(left, right)))) + node <- Gen.oneOf(nodeCons.map(cons => cons(Array(left, right)))) } yield node def logicalExprTreeGen(nodeCons: Seq[LogicalTransformerCons]): Gen[Value[SBoolean.type]] = diff --git a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 805ebdf29e..2c42abdeea 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -543,7 +543,7 @@ class BasicOpsSpecification extends SigmaTestingCommons { val byteArrayVar1Value = ByteArrayConstant(Array[Byte](1.toByte, 2.toByte)) test("EQArrayCollection", env + ("byteArrayVar1" -> byteArrayVar1Value), ext, "byteArrayVar1 == Coll[Byte](1.toByte, 2.toByte)", - EQ(byteArrayVar1Value, ConcreteCollection(Vector(ByteConstant(1), ByteConstant(2)), SByte)).toSigmaProp, + EQ(byteArrayVar1Value, ConcreteCollection(Array(ByteConstant(1), ByteConstant(2)), SByte)).toSigmaProp, true ) } @@ -553,8 +553,8 @@ class BasicOpsSpecification extends SigmaTestingCommons { "{ def inc(i: Int) = i + 1; inc(2) == 3 }", EQ( Apply( - FuncValue(Vector((1, SInt)), Plus(ValUse(1, SInt), IntConstant(1))), - Vector(IntConstant(2)) + FuncValue(Array((1, SInt)), Plus(ValUse(1, SInt), IntConstant(1))), + Array(IntConstant(2)) ), IntConstant(3)).toSigmaProp ) @@ -568,10 +568,10 @@ class BasicOpsSpecification extends SigmaTestingCommons { | blake2b256(out.propositionBytes) != Coll[Byte](1.toByte) |}) """.stripMargin, - ForAll(Outputs, FuncValue(Vector((1,SBox)), + ForAll(Outputs, FuncValue(Array((1,SBox)), BinAnd( GE(ExtractRegisterAs(ValUse(1,SBox), ErgoBox.R5, SOption(SInt)).get, Plus(Height, IntConstant(10))), - NEQ(CalcBlake2b256(ExtractScriptBytes(ValUse(1,SBox))), ConcreteCollection(Vector(ByteConstant(1.toByte)), SByte)) + NEQ(CalcBlake2b256(ExtractScriptBytes(ValUse(1,SBox))), ConcreteCollection(Array(ByteConstant(1.toByte)), SByte)) ))).toSigmaProp, true ) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala index 1c22f04ad2..5daf3b7037 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala @@ -408,10 +408,10 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { }""".stripMargin val expectedPropTree = ForAll( - ConcreteCollection(Vector(IntConstant(0), IntConstant(1), IntConstant(2), IntConstant(3), IntConstant(4), IntConstant(5)), SInt), - FuncValue(Vector((1, SInt)), + ConcreteCollection(Array(IntConstant(0), IntConstant(1), IntConstant(2), IntConstant(3), IntConstant(4), IntConstant(5)), SInt), + FuncValue(Array((1, SInt)), BlockValue( - Vector(ValDef(3, If(EQ(ValUse(1, SInt), IntConstant(0)), IntConstant(5), Minus(ValUse(1, SInt), IntConstant(1))))), + Array(ValDef(3, If(EQ(ValUse(1, SInt), IntConstant(0)), IntConstant(5), Minus(ValUse(1, SInt), IntConstant(1))))), BinAnd(GE(ValUse(3, SInt), IntConstant(0)), LE(ValUse(3, SInt), IntConstant(5))) ) ) @@ -434,14 +434,14 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { }""".stripMargin val expectedPropTree = ForAll( - ConcreteCollection(Vector(IntConstant(0), IntConstant(1), IntConstant(2), IntConstant(3), IntConstant(4), IntConstant(5)), SInt), + ConcreteCollection(Array(IntConstant(0), IntConstant(1), IntConstant(2), IntConstant(3), IntConstant(4), IntConstant(5)), SInt), FuncValue( - Vector((1, SInt)), + Array((1, SInt)), BlockValue( - Vector( + Array( ValDef(3, ByIndex( - ConcreteCollection(Vector(IntConstant(1), IntConstant(1), IntConstant(0), IntConstant(0), IntConstant(0), IntConstant(1)), SInt), + ConcreteCollection(Array(IntConstant(1), IntConstant(1), IntConstant(0), IntConstant(0), IntConstant(0), IntConstant(1)), SInt), If( LE(ValUse(1, SInt), IntConstant(0)), IntConstant(5), diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala index 6a84228622..50ac90abe0 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala @@ -168,7 +168,7 @@ class ThresholdSpecification extends SigmaTestingCommons { // for each test case, make into atleast and reduce it to crypto with different thresholds for (t <- testCaseSeq) { for (bound <- 0 to testCaseSeq.length + 1) { - val pReduced = prover.reduceToCrypto(ctx, AtLeast(bound, t.vector)) + val pReduced = prover.reduceToCrypto(ctx, AtLeast(bound, t.vector.toArray)) pReduced.fold(t => throw t, _ => true) shouldBe true if (t.dlogOnlyVector.v.isEmpty) { // Case 0: no ProveDlogs in the test vector -- just booleans if (t.numTrue >= bound) { @@ -355,7 +355,7 @@ class ThresholdSpecification extends SigmaTestingCommons { for (bound <- 1 to i) { // don't go beyond i -- "threshold reduce to crypto" tests that atLeast then becomes false // don't test bound 0 -- "threshold reduce to crypto" tests that atLeast then becomes true - val pureAtLeastProp = AtLeast(bound, propComponents.slice(0, i)) + val pureAtLeastProp = AtLeast(bound, propComponents.slice(0, i).toArray) val OrPlusAtLeastOnRightProp = SigmaOr(secret6.publicImage, pureAtLeastProp) val OrPlusAtLeastOnLeftProp = SigmaOr(pureAtLeastProp, secret6.publicImage) val AndPlusAtLeastOnLeftProp = SigmaAnd(pureAtLeastProp, secret6.publicImage) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala index 3952bef3a1..42bcf6bbe5 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/AtomicSwapExampleSpecification.scala @@ -81,7 +81,7 @@ class AtomicSwapExampleSpecification extends SigmaTestingCommons { pubkeyB), SigmaAnd( AND( - ConcreteCollection(Vector( + ConcreteCollection(Array( LT(SizeOf(ValUse(1, SCollection(SByte))), IntConstant(33)), EQ(CalcBlake2b256(ValUse(1, SCollection(SByte))), hx)), SBoolean) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala index 7d6bd0615c..10e391a893 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala @@ -355,7 +355,7 @@ class Rule110Specification extends SigmaTestingCommons { val t = TrueLeaf val f = FalseLeaf - val rule110 = OR(Seq( + val rule110 = OR(Array( AND(EQ(input0, t), EQ(input1, t), EQ(input2, t), EQ(output, f)), AND(EQ(input0, t), EQ(input1, t), EQ(input2, f), EQ(output, t)), AND(EQ(input0, t), EQ(input1, f), EQ(input2, t), EQ(output, t)), @@ -366,7 +366,7 @@ class Rule110Specification extends SigmaTestingCommons { AND(EQ(input0, f), EQ(input1, f), EQ(input2, f), EQ(output, f)) )) - val prop = AND(Seq( + val prop = AND(Array( EQ(SizeOf(Inputs), IntConstant(3)), EQ(SizeOf(Outputs), IntConstant(4)), @@ -400,7 +400,7 @@ class Rule110Specification extends SigmaTestingCommons { val row = RowReg -> LongConstant(0) val column = ColumnReg -> LongConstant(col) val value = if (col == 15) ValueReg -> TrueLeaf else ValueReg -> FalseLeaf - ErgoBox(0L, prop, 0, Seq(), Map(row, column, value), txId.toModifierId, col.toShort) + ErgoBox(0L, prop, 0, Nil, Map(row, column, value), txId.toModifierId, col.toShort) } val initBlock = FullBlock( From 92ca37b9f96440d1a6a30197ff8a2a0c8688c9b6 Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Wed, 30 Oct 2019 18:00:26 +0300 Subject: [PATCH 13/16] update ergoBranch --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 4e02fad2f2..064211292c 100644 --- a/build.sbt +++ b/build.sbt @@ -299,7 +299,7 @@ lazy val rootSettings = Seq( ) def runErgoTask(task: String, sigmastateVersion: String, log: Logger): Unit = { - val ergoBranch = "sigma-core-opt" + val ergoBranch = "master" val sbtEnvVars = Seq("BUILD_ENV" -> "test", "SIGMASTATE_VERSION" -> sigmastateVersion) log.info(s"Testing current build in Ergo (branch $ergoBranch):") From 2d4e5e3c0d11f28281e5e4acc85c5259caf8f5bd Mon Sep 17 00:00:00 2001 From: Denys Zadorozhnyi Date: Mon, 9 Dec 2019 14:40:12 +0200 Subject: [PATCH 14/16] update spam tests branch; --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 064211292c..43282a312c 100644 --- a/build.sbt +++ b/build.sbt @@ -353,7 +353,7 @@ commands += Command.command("ergoItTest") { state => } def runSpamTestTask(task: String, sigmastateVersion: String, log: Logger): Unit = { - val spamBranch = "master" + val spamBranch = "revert-23-revert-22-serialize-opt" val envVars = Seq("SIGMASTATE_VERSION" -> sigmastateVersion, "SPECIAL_VERSION" -> specialVersion, // SSH_SPAM_REPO_KEY should be set (see Jenkins Credentials Binding Plugin) From e3e5a69c2866f98cf9a8ae6c2f28dcd46c20adfa Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Tue, 14 Jan 2020 09:16:34 +0300 Subject: [PATCH 15/16] addressing review comments --- sigmastate/src/main/scala/sigmastate/Values.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sigmastate/src/main/scala/sigmastate/Values.scala b/sigmastate/src/main/scala/sigmastate/Values.scala index fb58e685b4..d05f05a82e 100644 --- a/sigmastate/src/main/scala/sigmastate/Values.scala +++ b/sigmastate/src/main/scala/sigmastate/Values.scala @@ -669,7 +669,13 @@ object Values { case class ConcreteCollection[V <: SType](items: Seq[Value[V]], elementType: V) extends EvaluatedCollection[V, SCollection[V]] { -// TODO uncomment and make sure Ergo works with it, i.e. complex data types are never used for `items` +// TODO uncomment and make sure Ergo works with it, i.e. complex data types are never used for `items`. +// There is nothing wrong in using List, Vector and other fancy types as a concrete representation +// of `items`, but these types have sub-optimal performance (2-3x overhead comparing to WrappedArray) +// which is immediately visible in profile. +// NOTE, the assert below should be commented before production release. +// Is it there for debuging only, basically to catch call stacks where the fancy types may +// occasionally be used. // assert(items.isInstanceOf[mutable.WrappedArray[_]] || items.isInstanceOf[mutable.IndexedSeq[_]], // s"Invalid types of items ${items.getClass}") private val isBooleanConstants = elementType == SBoolean && items.forall(_.isInstanceOf[Constant[_]]) From 829f5da7698c1b732b20db26bf5ca6f79d343c4f Mon Sep 17 00:00:00 2001 From: Alexander Slesarenko Date: Fri, 17 Jan 2020 13:59:08 +0300 Subject: [PATCH 16/16] simplify code using TryOps.getOrThrow --- .../sigmastate/eval/CostingDataContext.scala | 4 ++-- .../sigmastate/interpreter/Interpreter.scala | 5 ++--- .../interpreter/ProverInterpreter.scala | 2 +- .../main/scala/sigmastate/utils/Helpers.scala | 2 ++ .../ergoplatform/ErgoAddressSpecification.scala | 4 ++-- .../org/ergoplatform/ErgoScriptPredefSpec.scala | 16 ++++++++-------- .../SoftForkabilitySpecification.scala | 2 +- .../TestingInterpreterSpecification.scala | 16 ++++++++-------- .../DeserializationResilience.scala | 2 +- .../sigmastate/utxo/BasicOpsSpecification.scala | 2 +- .../utxo/CollectionOperationsSpecification.scala | 8 ++++---- .../utxo/ErgoLikeInterpreterSpecification.scala | 14 +++++++------- .../sigmastate/utxo/FuncVarSpecification.scala | 2 +- .../sigmastate/utxo/ThresholdSpecification.scala | 2 +- .../BlockchainSimulationTestingCommons.scala | 2 +- .../examples/OracleExamplesSpecification.scala | 8 ++++---- 16 files changed, 46 insertions(+), 45 deletions(-) diff --git a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala index 5b34e3eda4..81ce7fb44a 100644 --- a/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/sigmastate/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -372,8 +372,8 @@ object CostingBox { // val eRange = asElem[Any](IR.rtypeToElem(tRange)) // // IR.verifyCalcFunc[Any => Any](asRep[Context => (Any => Any)](calcF), IR.funcElement(eDom, eRange)) -//// IR.verifyCostFunc(costF).fold(t => throw t, x => x) -//// IR.verifyIsProven(calcF).fold(t => throw t, x => x) +//// IR.verifyCostFunc(costF).getOrThrow +//// IR.verifyIsProven(calcF).getOrThrow // // // check cost //// val costingCtx = context.toSigmaContext(IR, isCost = true) diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala index 293ea4af22..f867715b13 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/Interpreter.scala @@ -152,8 +152,7 @@ trait Interpreter extends ScorexLogging { CheckCostFunc(IR)(asRep[Any => Int](costF)) val costingCtx = context.toSigmaContext(IR, isCost = true) - val estimatedCost = IR.checkCostWithContext(costingCtx, exp, costF, maxCost, initCost) - .fold(t => throw t, identity) + val estimatedCost = IR.checkCostWithContext(costingCtx, exp, costF, maxCost, initCost).getOrThrow IR.onEstimatedCost(env, exp, costingRes, costingCtx, estimatedCost) @@ -224,7 +223,7 @@ trait Interpreter extends ScorexLogging { // here we assume that when `propTree` is TrueProp then `reduceToCrypto` always succeeds // and the rest of the verification is also trivial - val (cProp, cost) = reduceToCrypto(context2, env, propTree).fold(t => throw t, identity) + val (cProp, cost) = reduceToCrypto(context2, env, propTree).getOrThrow val checkingResult = cProp match { case TrivialProp.TrueProp => true diff --git a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala index dd2001a612..81b642ceaf 100644 --- a/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala +++ b/sigmastate/src/main/scala/sigmastate/interpreter/ProverInterpreter.scala @@ -138,7 +138,7 @@ trait ProverInterpreter extends Interpreter with AttributionCore { val prop = propositionFromErgoTree(tree, ctxUpdInitCost) val (propTree, _) = applyDeserializeContext(ctxUpdInitCost, prop) val tried = reduceToCrypto(ctxUpdInitCost, env, propTree) - val (reducedProp, cost) = tried.fold(t => throw t, identity) + val (reducedProp, cost) = tried.getOrThrow def errorReducedToFalse = error("Script reduced to false") diff --git a/sigmastate/src/main/scala/sigmastate/utils/Helpers.scala b/sigmastate/src/main/scala/sigmastate/utils/Helpers.scala index b9e67c8208..3de68fe459 100644 --- a/sigmastate/src/main/scala/sigmastate/utils/Helpers.scala +++ b/sigmastate/src/main/scala/sigmastate/utils/Helpers.scala @@ -103,6 +103,8 @@ object Helpers { case Success(value) => Right(value) case Failure(t) => Left(t) } + def mapOrThrow[B](f: A => B): B = source.fold(t => throw t, f) + def getOrThrow: A = source.fold(t => throw t, identity) } implicit class DecoderResultOps[A](val source: Decoder.Result[A]) extends AnyVal { diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala index 64c6fe4b3e..b7ae2b050a 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala @@ -104,10 +104,10 @@ class ErgoAddressSpecification extends PropSpec val env: ScriptEnv = Map() val prover = new ErgoLikeTestProvingInterpreter() - val pr = prover.prove(env + (ScriptNameProp -> s"prove"), address.script, ctx, fakeMessage).fold(t => throw t, identity) + val pr = prover.prove(env + (ScriptNameProp -> s"prove"), address.script, ctx, fakeMessage).getOrThrow val verifier = new ErgoLikeTestInterpreter - verifier.verify(env + (ScriptNameProp -> s"verify_ext"), address.script, ctx, pr.proof, fakeMessage).get._1 shouldBe true + verifier.verify(env + (ScriptNameProp -> s"verify_ext"), address.script, ctx, pr.proof, fakeMessage).getOrThrow._1 shouldBe true } property("spending a box protected by P2SH contract") { diff --git a/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala index a64b814e49..c58455ba76 100644 --- a/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala +++ b/sigmastate/src/test/scala/org/ergoplatform/ErgoScriptPredefSpec.scala @@ -146,11 +146,11 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { // should not be able to collect before minerRewardDelay val prove = prover.prove(emptyEnv + (ScriptNameProp -> "rewardOutputScript_prove"), prop, ctx, fakeMessage).get verifier.verify(emptyEnv + (ScriptNameProp -> "rewardOutputScript_verify"), prop, prevBlockCtx, prove, fakeMessage) - .fold(t => throw t, x => x) should matchPattern { case (false,_) => } + .getOrThrow should matchPattern { case (false,_) => } // should be able to collect after minerRewardDelay - val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).get - verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).get._1 shouldBe true + val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).getOrThrow + verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true } property("create transaction collecting the emission box") { @@ -225,8 +225,8 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { spendingTransaction, self = inputBoxes.head).withCostLimit(CostTable.ScriptLimit * 10) - val pr = prover.prove(emptyEnv + (ScriptNameProp -> "tokenThresholdScript_prove"), prop, ctx, fakeMessage).fold(t => throw t, x => x) - verifier.verify(emptyEnv + (ScriptNameProp -> "tokenThresholdScript_verify"), prop, ctx, pr, fakeMessage).get._1 shouldBe true + val pr = prover.prove(emptyEnv + (ScriptNameProp -> "tokenThresholdScript_prove"), prop, ctx, fakeMessage).getOrThrow + verifier.verify(emptyEnv + (ScriptNameProp -> "tokenThresholdScript_verify"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true } @@ -257,7 +257,7 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { ErgoBox(20, prop, 0, Seq((wrongId, 1)), Map()), ErgoBox(20, prop, 0, Seq((tokenId, tokenAmount / 2 + 1), (wrongId2, 1)), Map()) ) - check(inputs3).fold(t => throw t, identity) + check(inputs3).getOrThrow // A transaction which contains input with no tokens val inputs4 = IndexedSeq( @@ -301,8 +301,8 @@ class ErgoScriptPredefSpec extends SigmaTestingCommons { boxesToSpend = inputBoxes, spendingTransaction, self = inputBoxes.head) - val pr = prover.prove(emptyEnv + (ScriptNameProp -> "checkRewardTx_prove"), prop, ctx, fakeMessage).fold(t => throw t, identity) - verifier.verify(emptyEnv + (ScriptNameProp -> "checkRewardTx_verify"), prop, ctx, pr, fakeMessage).fold(t => throw t, identity)._1 shouldBe true + val pr = prover.prove(emptyEnv + (ScriptNameProp -> "checkRewardTx_prove"), prop, ctx, fakeMessage).getOrThrow + verifier.verify(emptyEnv + (ScriptNameProp -> "checkRewardTx_verify"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true spendingTransaction } diff --git a/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index fa087fccef..95c7fedf70 100644 --- a/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -55,7 +55,7 @@ class SoftForkabilitySpecification extends SigmaTestingData { val env = Map(ScriptNameProp -> (name + "_verify")) val ctx = createContext(blockHeight, tx, vs) val prop = tx.outputs(0).ergoTree - verifier.verify(env, prop, ctx, proof, fakeMessage).map(_._1).fold(t => throw t, identity) shouldBe true + verifier.verify(env, prop, ctx, proof, fakeMessage).map(_._1).getOrThrow shouldBe true } def proveAndVerifyTx(name: String, tx: ErgoLikeTransaction, vs: SigmaValidationSettings) = { diff --git a/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala index 2fc0497495..9a2091a0cb 100644 --- a/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/TestingInterpreterSpecification.scala @@ -280,16 +280,16 @@ class TestingInterpreterSpecification extends SigmaTestingCommons { val proof = NoProof val env = testingContext(99) - verifier.verify(prop1, env, proof, challenge).map(_._1).fold(t => throw t, identity) shouldBe true + verifier.verify(prop1, env, proof, challenge).map(_._1).getOrThrow shouldBe true val prop2 = OR(TrueLeaf, FalseLeaf).toSigmaProp - verifier.verify(prop2, env, proof, challenge).map(_._1).fold(t => throw t, identity) shouldBe true + verifier.verify(prop2, env, proof, challenge).map(_._1).getOrThrow shouldBe true val prop3 = AND(TrueLeaf, TrueLeaf).toSigmaProp - verifier.verify(prop3, env, proof, challenge).map(_._1).fold(t => throw t, identity) shouldBe true + verifier.verify(prop3, env, proof, challenge).map(_._1).getOrThrow shouldBe true val prop4 = GT(Height, IntConstant(90)).toSigmaProp - verifier.verify(prop4, env, proof, challenge).map(_._1).fold(t => throw t, identity) shouldBe true + verifier.verify(prop4, env, proof, challenge).map(_._1).getOrThrow shouldBe true } property("Evaluation - no real proving - false case") { @@ -299,16 +299,16 @@ class TestingInterpreterSpecification extends SigmaTestingCommons { val proof = NoProof val env = testingContext(99) - verifier.verify(prop1, env, proof, challenge).map(_._1).fold(t => throw t, identity) shouldBe false + verifier.verify(prop1, env, proof, challenge).map(_._1).getOrThrow shouldBe false val prop2 = OR(FalseLeaf, FalseLeaf).toSigmaProp - verifier.verify(prop2, env, proof, challenge).map(_._1).fold(t => throw t, identity) shouldBe false + verifier.verify(prop2, env, proof, challenge).map(_._1).getOrThrow shouldBe false val prop3 = AND(FalseLeaf, TrueLeaf).toSigmaProp - verifier.verify(prop3, env, proof, challenge).map(_._1).fold(t => throw t, identity) shouldBe false + verifier.verify(prop3, env, proof, challenge).map(_._1).getOrThrow shouldBe false val prop4 = GT(Height, IntConstant(100)).toSigmaProp - verifier.verify(prop4, env, proof, challenge).map(_._1).fold(t => throw t, identity) shouldBe false + verifier.verify(prop4, env, proof, challenge).map(_._1).getOrThrow shouldBe false } property("Evaluation - hash function") { diff --git a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala index 04811c5f31..7d0f9aaf9f 100644 --- a/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala +++ b/sigmastate/src/test/scala/sigmastate/serialization/DeserializationResilience.scala @@ -269,7 +269,7 @@ class DeserializationResilience extends SerializationSpecification with SigmaTes verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), ErgoTree(ErgoTree.DefaultHeader, IndexedSeq(), recursiveScript), ctx, pr, fakeMessage) } - res.fold(t => throw t, identity) + res.getOrThrow }, { case e: NoSuchElementException => // this is expected because of deserialization is forced when ErgoTree.complexity is accessed in verify diff --git a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala index 2c42abdeea..d3253f26f1 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/BasicOpsSpecification.scala @@ -82,7 +82,7 @@ class BasicOpsSpecification extends SigmaTestingCommons { lastBlockUtxoRoot = AvlTreeData.dummy, ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(boxToSpend), spendingTransaction = tx, self = boxToSpend) - val pr = prover.prove(env + (ScriptNameProp -> s"${name}_prove"), prop, ctx, fakeMessage).fold(t => throw t, identity) + val pr = prover.prove(env + (ScriptNameProp -> s"${name}_prove"), prop, ctx, fakeMessage).getOrThrow val ctxExt = ctx.withExtension(pr.extension) diff --git a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala index 5daf3b7037..3eebdd1e28 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/CollectionOperationsSpecification.scala @@ -34,16 +34,16 @@ class CollectionOperationsSpecification extends SigmaTestingCommons { outputBoxValues: IndexedSeq[Long], boxesToSpendValues: IndexedSeq[Long] = IndexedSeq()) = { val (prover, verifier, prop, ctx) = buildEnv(code, expectedComp, outputBoxValues, boxesToSpendValues) - val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).fold(t => throw t, x => x) - verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).get._1 shouldBe true + val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).getOrThrow + verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true } private def assertProof(code: String, outputBoxValues: IndexedSeq[Long], boxesToSpendValues: IndexedSeq[Long]) = { val (prover, verifier, prop, ctx) = buildEnv(code, None, outputBoxValues, boxesToSpendValues) - val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).fold(t => throw t, x => x) - verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).get._1 shouldBe true + val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).getOrThrow + verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true } private def assertProverFail(code: String, diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala index 50eeea025f..99533b2521 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ErgoLikeInterpreterSpecification.scala @@ -363,8 +363,8 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons spendingTransaction, self = s1) - val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).fold(t => throw t, x => x) - verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).fold(t => throw t, x => x)._1 shouldBe true + val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).getOrThrow + verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true //make sure that wrong case couldn't be proved @@ -466,8 +466,8 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons spendingTransaction, self = s) - val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove_prop"), prop, ctx, fakeMessage).fold(t => throw t, x => x) - verifier.verify(emptyEnv + (ScriptNameProp -> "verify_prop"), prop, ctx, pr, fakeMessage).fold(t => throw t, x => x)._1 shouldBe true + val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove_prop"), prop, ctx, fakeMessage).getOrThrow + verifier.verify(emptyEnv + (ScriptNameProp -> "verify_prop"), prop, ctx, pr, fakeMessage).getOrThrow._1 shouldBe true val wrongCtx = ErgoLikeContextTesting( currentHeight = 50, @@ -478,7 +478,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons self = s) prover.prove(prop, wrongCtx, fakeMessage).isFailure shouldBe true - verifier.verify(prop, wrongCtx, pr, fakeMessage).fold(t => throw t, x => x)._1 shouldBe false + verifier.verify(prop, wrongCtx, pr, fakeMessage).getOrThrow._1 shouldBe false val prop2 = compile(env, """{ @@ -490,7 +490,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons prover.prove(emptyEnv + (ScriptNameProp -> "prove_prop2"), prop2, ctx, fakeMessage).isFailure shouldBe true verifier .verify(emptyEnv + (ScriptNameProp -> "verify_prop2"), prop2, ctx, pr, fakeMessage) - .fold(t => throw t, x => x)._1 shouldBe false + .getOrThrow._1 shouldBe false } /** @@ -647,7 +647,7 @@ class ErgoLikeInterpreterSpecification extends SigmaTestingCommons self = box) an[RuntimeException] should be thrownBy - prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).fold(t => throw t, x => x) + prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).getOrThrow } property("DeserializeContext value(script) type mismatch") { diff --git a/sigmastate/src/test/scala/sigmastate/utxo/FuncVarSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/FuncVarSpecification.scala index 6576a1d77e..335a341483 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/FuncVarSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/FuncVarSpecification.scala @@ -23,7 +23,7 @@ class FuncVarSpecification extends SigmaTestingCommons { // val prover = new ContextEnrichingTestProvingInterpreter() // .withContextExtender(scriptId, Constant(CFunc[Int, Int](ctx, code).asWrappedType, SFunc(SInt, SInt))) // val prop = compileWithCosting(emptyEnv, s"{ val f = getVar[Int => Int](1).get; f(10) > 0 }").asBoolValue.asSigmaProp -// val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).fold(t => throw t, identity) +// val pr = prover.prove(emptyEnv + (ScriptNameProp -> "prove"), prop, ctx, fakeMessage).getOrThrow // } } diff --git a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala index 50ac90abe0..b3a0f1f95e 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/ThresholdSpecification.scala @@ -169,7 +169,7 @@ class ThresholdSpecification extends SigmaTestingCommons { for (t <- testCaseSeq) { for (bound <- 0 to testCaseSeq.length + 1) { val pReduced = prover.reduceToCrypto(ctx, AtLeast(bound, t.vector.toArray)) - pReduced.fold(t => throw t, _ => true) shouldBe true + pReduced.mapOrThrow(_ => true) shouldBe true if (t.dlogOnlyVector.v.isEmpty) { // Case 0: no ProveDlogs in the test vector -- just booleans if (t.numTrue >= bound) { pReduced.get._1 shouldBe TrueProp diff --git a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala index c37694ffd3..7f19aaa06c 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala @@ -32,7 +32,7 @@ trait BlockchainSimulationTestingCommons extends SigmaTestingCommons { case _ => val block = generateBlock(state, miner, currentLevel, propOpt, extension) val updStateTry = state.applyBlock(block) - updStateTry.fold(t => throw t, identity) + updStateTry.getOrThrow checkState(updStateTry.get, miner, currentLevel + 1, limit, propOpt, extension) } diff --git a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala index 2feb15cf14..9e67015e57 100644 --- a/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala +++ b/sigmastate/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala @@ -183,14 +183,14 @@ class OracleExamplesSpecification extends SigmaTestingCommons { suite => val alice = aliceTemplate .withContextExtender(22: Byte, BoxConstant(oracleBox)) .withContextExtender(23: Byte, ByteArrayConstant(proof)) - val prA = alice.prove(emptyEnv + (ScriptNameProp -> "alice_prove"), propAlice, ctx, fakeMessage).fold(t => throw t, x => x) + val prA = alice.prove(emptyEnv + (ScriptNameProp -> "alice_prove"), propAlice, ctx, fakeMessage).getOrThrow - val prB = bob.prove(emptyEnv + (ScriptNameProp -> "bob_prove"), propBob, ctx, fakeMessage).fold(t => throw t, x => x) + val prB = bob.prove(emptyEnv + (ScriptNameProp -> "bob_prove"), propBob, ctx, fakeMessage).getOrThrow val ctxv = ctx.withExtension(prA.extension) - verifier.verify(emptyEnv + (ScriptNameProp -> "alice_verify"), propAlice, ctxv, prA, fakeMessage).get._1 shouldBe true + verifier.verify(emptyEnv + (ScriptNameProp -> "alice_verify"), propAlice, ctxv, prA, fakeMessage).getOrThrow._1 shouldBe true - verifier.verify(emptyEnv + (ScriptNameProp -> "bob_verify"), propBob, ctx, prB, fakeMessage).get._1 shouldBe true + verifier.verify(emptyEnv + (ScriptNameProp -> "bob_verify"), propBob, ctx, prB, fakeMessage).getOrThrow._1 shouldBe true //todo: check timing conditions - write tests for height < 40 and >= 60 }