diff --git a/core/shared/src/main/scala/sigma/VersionContext.scala b/core/shared/src/main/scala/sigma/VersionContext.scala index 14e6dc8b21..70af100357 100644 --- a/core/shared/src/main/scala/sigma/VersionContext.scala +++ b/core/shared/src/main/scala/sigma/VersionContext.scala @@ -41,8 +41,8 @@ object VersionContext { val JitActivationVersion: Byte = 2 private val _defaultContext = VersionContext( - activatedVersion = 1/* v4.x */, - ergoTreeVersion = 1 + activatedVersion = 2/* v5.x */, + ergoTreeVersion = 2 ) /** Universally accessible version context which is used to version the code diff --git a/interpreter/shared/src/main/scala/org/ergoplatform/ErgoAddress.scala b/interpreter/shared/src/main/scala/org/ergoplatform/ErgoAddress.scala index 100fc383a6..0e0b60ab6e 100644 --- a/interpreter/shared/src/main/scala/org/ergoplatform/ErgoAddress.scala +++ b/interpreter/shared/src/main/scala/org/ergoplatform/ErgoAddress.scala @@ -10,8 +10,9 @@ import sigmastate.crypto.DLogProtocol.{ProveDlog, ProveDlogProp} import sigmastate.exceptions.SigmaException import sigmastate.serialization._ import sigmastate.utxo.{DeserializeContext, Slice} -import sigma.Coll +import sigma.{Coll, VersionContext} import sigma.ast.{SInt, SSigmaProp} +import sigmastate.Values.ErgoTree.{ZeroHeader, setVersionBits} import scala.util.Try @@ -164,7 +165,11 @@ class Pay2SHAddress(val scriptHash: Array[Byte])(implicit val encoder: ErgoAddre ByteArrayConstant(scriptHash) ) val scriptIsCorrect = DeserializeContext(scriptId, SSigmaProp) - ErgoTree.withoutSegregation(SigmaAnd(hashEquals.toSigmaProp, scriptIsCorrect)) + // Get script version either from the default context or from a context provided by an application + // This is never part of the consensus and can be controlled by applications + val treeVersion = VersionContext.current.ergoTreeVersion + val header = setVersionBits(ZeroHeader, treeVersion) + ErgoTree.withoutSegregation(header, SigmaAnd(hashEquals.toSigmaProp, scriptIsCorrect)) } override def equals(obj: Any): Boolean = obj match { diff --git a/interpreter/shared/src/main/scala/org/ergoplatform/ErgoTreePredef.scala b/interpreter/shared/src/main/scala/org/ergoplatform/ErgoTreePredef.scala index fb4dd6b5d1..4ff57772d8 100644 --- a/interpreter/shared/src/main/scala/org/ergoplatform/ErgoTreePredef.scala +++ b/interpreter/shared/src/main/scala/org/ergoplatform/ErgoTreePredef.scala @@ -6,6 +6,7 @@ import sigma.ast.{SBox, SInt, SLong, SSigmaProp} import sigmastate.crypto.DLogProtocol.ProveDlog import sigmastate.crypto.CryptoConstants import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer +import sigmastate.Values.ErgoTree.{HeaderType, ZeroHeader} import sigmastate.Values.{ErgoTree, FalseSigmaProp, IntArrayConstant, IntConstant, LongConstant, SigmaPropConstant, SigmaPropValue, TrueSigmaProp, Value} import sigmastate.utxo._ import sigmastate._ @@ -14,17 +15,17 @@ import sigmastate.lang.Terms.ValueOps object ErgoTreePredef { /** Create ErgoTree with `false` proposition, which is never true. * - * @param headerFlags ErgoTree header flags to be combined with default header + * @param header ErgoTree header to be used in the tree * @see ErgoTree.headerWithVersion() */ - def FalseProp(headerFlags: Byte): ErgoTree = ErgoTree.withoutSegregation(headerFlags, FalseSigmaProp) + def FalseProp(header: HeaderType): ErgoTree = ErgoTree.withoutSegregation(header, FalseSigmaProp) /** Create ErgoTree with `true` proposition, which is always true. * - * @param headerFlags ErgoTree header flags to be combined with default header + * @param header ErgoTree header to be used in the tree * @see ErgoTree.headerWithVersion() */ - def TrueProp(headerFlags: Byte): ErgoTree = ErgoTree.withoutSegregation(headerFlags, TrueSigmaProp) + def TrueProp(header: HeaderType): ErgoTree = ErgoTree.withoutSegregation(header, TrueSigmaProp) /** * Byte array value of the serialized reward output script proposition with pk being substituted @@ -50,10 +51,10 @@ object ErgoTreePredef { * Required script of the box, that collects mining rewards */ def rewardOutputScript(delta: Int, minerPk: ProveDlog): ErgoTree = { - SigmaAnd( + ErgoTree.withSegregation(ZeroHeader, SigmaAnd( GE(Height, Plus(boxCreationHeight(Self), IntConstant(delta))).toSigmaProp, SigmaPropConstant(minerPk) - ).treeWithSegregation + )) } /** @@ -62,11 +63,11 @@ object ErgoTreePredef { */ def feeProposition(delta: Int = 720): ErgoTree = { val out = ByIndex(Outputs, IntConstant(0)) - AND( + ErgoTree.withSegregation(ZeroHeader, AND( EQ(Height, boxCreationHeight(out)), EQ(ExtractScriptBytes(out), expectedMinerOutScriptBytesVal(delta, MinerPubkey)), EQ(SizeOf(Outputs), 1) - ).toSigmaProp.treeWithSegregation + ).toSigmaProp) } /** @@ -92,11 +93,13 @@ object ErgoTreePredef { EQ(ExtractScriptBytes(minerOut), expectedMinerOutScriptBytesVal(s.minerRewardDelay, MinerPubkey)), EQ(Height, boxCreationHeight(minerOut)) ) - AND( - heightIncreased, - correctMinerOutput, - OR(AND(outputsNum, sameScriptRule, correctCoinsConsumed, heightCorrect), lastCoins) - ).toSigmaProp.treeWithSegregation + ErgoTree.withSegregation(ZeroHeader, + AND( + heightIncreased, + correctMinerOutput, + OR(AND(outputsNum, sameScriptRule, correctCoinsConsumed, heightCorrect), lastCoins) + ).toSigmaProp + ) } /** @@ -153,7 +156,7 @@ object ErgoTreePredef { // check, that additional rules defined by foundation members are satisfied val customProposition = DeserializeRegister(ErgoBox.R4, SSigmaProp) // combine 3 conditions above with AND conjunction - SigmaAnd(amountCorrect.toSigmaProp, sameScriptRule.toSigmaProp, customProposition).treeWithSegregation + ErgoTree.withSegregation(ZeroHeader, SigmaAnd(amountCorrect.toSigmaProp, sameScriptRule.toSigmaProp, customProposition)) } /** diff --git a/interpreter/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala b/interpreter/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala index 4191421b10..f13b95436f 100644 --- a/interpreter/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala +++ b/interpreter/shared/src/main/scala/org/ergoplatform/validation/ValidationRules.scala @@ -2,6 +2,7 @@ package org.ergoplatform.validation import sigma.ast.{SGlobal, SOption, TypeCodes} import sigma.util.Extensions.toUByte +import sigmastate.Values.ErgoTree.HeaderType import sigmastate.Values.{ErgoTree, SValue} import sigmastate._ import sigmastate.exceptions._ @@ -241,7 +242,7 @@ object ValidationRules { object CheckHeaderSizeBit extends ValidationRule(1012, "For version greater then 0, size bit should be set.") with SoftForkWhenReplaced { - final def apply(header: Byte): Unit = { + final def apply(header: HeaderType): Unit = { checkRule() val version = ErgoTree.getVersion(header) if (version != 0 && !ErgoTree.hasSize(header)) { diff --git a/interpreter/shared/src/main/scala/sigmastate/UnprovenTree.scala b/interpreter/shared/src/main/scala/sigmastate/UnprovenTree.scala index 4e45c230f2..7375a0e83f 100644 --- a/interpreter/shared/src/main/scala/sigmastate/UnprovenTree.scala +++ b/interpreter/shared/src/main/scala/sigmastate/UnprovenTree.scala @@ -11,7 +11,9 @@ import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer import sigmastate.serialization.SigmaSerializer import sigmastate.utils.SigmaByteWriter import debox.cfor +import sigmastate.Values.ErgoTree.ZeroHeader import sigmastate.crypto.GF2_192_Poly + import scala.language.existentials object ConjectureType extends Enumeration { @@ -255,7 +257,7 @@ object FiatShamirTree { case _: UncheckedDiffieHellmanTuple | _: UnprovenDiffieHellmanTuple => ToBytes_DHT } fixedCostOp(costInfo) { - val propTree = ErgoTree.withSegregation(SigmaPropConstant(l.proposition)) + val propTree = ErgoTree.withSegregation(ZeroHeader, SigmaPropConstant(l.proposition)) val propBytes = DefaultSerializer.serializeErgoTree(propTree) val commitmentBytes = l.commitmentOpt.get.bytes w.put(leafPrefix) diff --git a/interpreter/shared/src/main/scala/sigmastate/Values.scala b/interpreter/shared/src/main/scala/sigmastate/Values.scala index e292eff463..964557730f 100644 --- a/interpreter/shared/src/main/scala/sigmastate/Values.scala +++ b/interpreter/shared/src/main/scala/sigmastate/Values.scala @@ -12,7 +12,7 @@ import sigmastate.interpreter.{CompanionDesc, ErgoTreeEvaluator, Interpreter, Na import sigmastate.serialization._ import sigmastate.serialization.OpCodes._ import sigmastate.TrivialProp.{FalseProp, TrueProp} -import sigmastate.Values.ErgoTree.substConstants +import sigmastate.Values.ErgoTree.{HeaderType, substConstants} import sigmastate.crypto.DLogProtocol.ProveDlog import sigmastate.crypto.{CryptoConstants, ProveDHTuple} import sigmastate.lang.Terms._ @@ -36,6 +36,7 @@ import sigma.{AvlTree, Coll, Colls, Header, PreHeader, _} import sigmastate.lang.SourceContext import sigma.util.safeNewArray import sigmastate.serialization.ValueCodes.{ConstantCode, OpCode} +import supertagged.TaggedType import scala.collection.compat.immutable.ArraySeq import scala.collection.mutable @@ -966,9 +967,8 @@ object Values { implicit class SigmaPropValueOps(val p: Value[SSigmaProp.type]) extends AnyVal { def isProven: Value[SBoolean.type] = SigmaPropIsProven(p) def propBytes: Value[SByteArray] = SigmaPropBytes(p) - def treeWithSegregation: ErgoTree = ErgoTree.withSegregation(p) - def treeWithSegregation(headerFlags: Byte): ErgoTree = - ErgoTree.withSegregation(headerFlags, p) + def treeWithSegregation(header: HeaderType): ErgoTree = + ErgoTree.withSegregation(header, p) } implicit class SigmaBooleanOps(val sb: SigmaBoolean) extends AnyVal { @@ -1217,7 +1217,7 @@ object Values { * this flag and provides it to the constructor. */ case class ErgoTree private[sigmastate]( - header: Byte, + header: HeaderType, constants: IndexedSeq[Constant[SType]], root: Either[UnparsedErgoTree, SigmaPropValue], private val givenComplexity: Int, @@ -1225,7 +1225,7 @@ object Values { private val givenDeserialize: Option[Boolean] ) { - def this(header: Byte, + def this(header: HeaderType, constants: IndexedSeq[Constant[SType]], root: Either[UnparsedErgoTree, SigmaPropValue]) = this( @@ -1334,11 +1334,12 @@ object Values { } object ErgoTree { - /** Current version of ErgoTree serialization format (aka bite-code language version)*/ - val VersionFlag: Byte = 0 + /** Represents information in ErgoTree header. */ + object HeaderType extends TaggedType[Byte] + type HeaderType = HeaderType.Type - /** Default value of ErgoTree.header byte */ - val DefaultHeader: Byte = (0 | VersionFlag).toByte + /** Current version of ErgoTree serialization format (aka bite-code language version)*/ + val VersionFlag: Byte = VersionContext.MaxSupportedScriptVersion /** Header flag to indicate that constant segregation should be applied. */ val ConstantSegregationFlag: Byte = 0x10 @@ -1349,34 +1350,66 @@ object Values { /** Header mask to extract version bits. */ val VersionMask: Byte = 0x07 + /** Header with all the flags set to 0 and version 0. */ + val ZeroHeader: HeaderType = HeaderType @@ 0.toByte + + /** Default value of ErgoTree.header byte */ + val DefaultHeader: HeaderType = ZeroHeader //HeaderType @@ (VersionFlag | SizeFlag).toByte + /** Default header with constant segregation enabled. */ - val ConstantSegregationHeader: Byte = (DefaultHeader | ConstantSegregationFlag).toByte + val ConstantSegregationHeader: HeaderType = HeaderType @@ (DefaultHeader | ConstantSegregationFlag).toByte /** @return true if the constant segregation flag is set to 1 in the given header byte. */ - @inline final def isConstantSegregation(header: Byte): Boolean = (header & ConstantSegregationFlag) != 0 + @inline final def isConstantSegregation(header: HeaderType): Boolean = (header & ConstantSegregationFlag) != 0 /** @return true if the size flag is set to 1 in the given header byte. */ - @inline final def hasSize(header: Byte): Boolean = (header & SizeFlag) != 0 + @inline final def hasSize(header: HeaderType): Boolean = (header & SizeFlag) != 0 /** @return a value of the version bits from the given header byte. */ - @inline final def getVersion(header: Byte): Byte = (header & VersionMask).toByte + @inline final def getVersion(header: HeaderType): Byte = (header & VersionMask).toByte - /** Update the version bits of the given header byte with the given version value. */ - @inline final def updateVersionBits(header: Byte, version: Byte): Byte = { + /** Update the version bits of the given header byte with the given version value, + * leaving all other bits unchanged. + */ + @inline final def setVersionBits(header: HeaderType, version: Byte): HeaderType = { require(version < 8, s"ErgoTree.version should be < 8: $version") - (header | version).toByte + val h = header & (~VersionMask) // clear version bits + HeaderType @@ (h | version).toByte + } + + /** Sets the required bit in the given header: + * - The SizeFlag is set if version > 0 + */ + @inline final def setRequiredBits(header: HeaderType): HeaderType = { + if (getVersion(header) > 0) { + // set SizeFlag if version is greater then 0 (see require() in ErgoTree constructor) + HeaderType @@ (header | ErgoTree.SizeFlag).toByte + } else + header + } + + /** Sets the ConstantSegregationFlag in the given header */ + @inline final def setConstantSegregation(header: HeaderType): HeaderType = { + HeaderType @@ (header | ConstantSegregationFlag).toByte + } + + /** Sets the ConstantSegregationFlag in the given header */ + @inline final def setSizeBit(header: HeaderType): HeaderType = { + HeaderType @@ (header | SizeFlag).toByte } /** Creates valid header byte with the given version. * The SizeFlag is set if version > 0 */ - @inline def headerWithVersion(version: Byte): Byte = { - // take default header and embedd the given version in it - var h = updateVersionBits(DefaultHeader, version) - if (version > 0) { - // set SizeFlag if version is greater then 0 (see require() in ErgoTree constructor) - h = (h | ErgoTree.SizeFlag).toByte - } - h + @inline final def defaultHeaderWithVersion(version: Byte): HeaderType = { + headerWithVersion(DefaultHeader, version) + } + + /** Creates valid header byte with the given version. + * The SizeFlag is set if version > 0 */ + @inline final def headerWithVersion(header: HeaderType, version: Byte): HeaderType = { + // take the header and embedd the given version in it + val h = setVersionBits(header, version) + setRequiredBits(h) } /** Substitute [[ConstantPlaceholder]] nodes in the given expression with the constants @@ -1396,55 +1429,49 @@ object Values { } /** Create an ErgoTree with the given parameters. */ - def apply(header: Byte, constants: IndexedSeq[Constant[SType]], root: SigmaPropValue): ErgoTree = { - new ErgoTree(header, constants, Right(root)) + def apply(header: HeaderType, constants: IndexedSeq[Constant[SType]], root: SigmaPropValue): ErgoTree = { + new ErgoTree(setRequiredBits(header), constants, Right(root)) } val EmptyConstants: IndexedSeq[Constant[SType]] = Array[Constant[SType]]() - /** Create new ErgoTree for the given proposition using the given header flags and - * without performing constant segregation. - */ - def withoutSegregation(root: SigmaPropValue): ErgoTree = - ErgoTree(ErgoTree.DefaultHeader, EmptyConstants, root) - - /** Create new ErgoTree for the given proposition using the given header flags and - * without performing constant segregation. - */ - def withoutSegregation(headerFlags: Byte, root: SigmaPropValue): ErgoTree = - ErgoTree((ErgoTree.DefaultHeader | headerFlags).toByte, EmptyConstants, root) - /** Create new ErgoTree for the given proposition using default header. * If the property is not a simple constant, then constant segregation is performed. */ - implicit def fromProposition(prop: SigmaPropValue): ErgoTree = { - fromProposition(ErgoTree.DefaultHeader, prop) + def fromProposition(prop: SigmaPropValue): ErgoTree = { + fromProposition(ErgoTree.ZeroHeader, prop) } /** Create new ErgoTree for the given proposition using the given header flags. * If the property is not a simple constant, then constant segregation is performed. */ - def fromProposition(headerFlags: Byte, prop: SigmaPropValue): ErgoTree = { + def fromProposition(header: HeaderType, prop: SigmaPropValue): ErgoTree = { prop match { - case SigmaPropConstant(_) => withoutSegregation(headerFlags, prop) - case _ => withSegregation(headerFlags, prop) + case SigmaPropConstant(_) => withoutSegregation(header, prop) + case _ => withSegregation(header, prop) } } /** Create new ErgoTree for the given sigma proposition using default header and * without performing constant segregation. */ - implicit def fromSigmaBoolean(pk: SigmaBoolean): ErgoTree = { - withoutSegregation(pk.toSigmaProp) + def fromSigmaBoolean(pk: SigmaBoolean): ErgoTree = { + withoutSegregation(ZeroHeader, pk.toSigmaProp) } /** Create new ErgoTree for the given sigma proposition using the given header flags * and without performing constant segregation. */ - def fromSigmaBoolean(headerFlags: Byte, pk: SigmaBoolean): ErgoTree = { - withoutSegregation(headerFlags, pk.toSigmaProp) + def fromSigmaBoolean(header: HeaderType, pk: SigmaBoolean): ErgoTree = { + withoutSegregation(header, pk.toSigmaProp) } + /** Create new ErgoTree for the given proposition using the given header flags and + * without performing constant segregation. + */ + def withoutSegregation(header: HeaderType, root: SigmaPropValue): ErgoTree = + ErgoTree(setRequiredBits(header), EmptyConstants, root) + /** Build ErgoTree via serialization of the value with ConstantSegregationHeader, constants segregated * from the tree and ConstantPlaceholders referring to the segregated constants. * @@ -1457,26 +1484,22 @@ object Values { * ConstantSegregationHeader flag. * @param prop expression to be transformed into ErgoTree **/ - def withSegregation(headerFlags: Byte, prop: SigmaPropValue): ErgoTree = { + def withSegregation(header: HeaderType, prop: SigmaPropValue): ErgoTree = { val constantStore = new ConstantStore() - val byteWriter = SigmaSerializer.startWriter(constantStore) + val w = SigmaSerializer.startWriter(constantStore) // serialize value and segregate constants into constantStore - ValueSerializer.serialize(prop, byteWriter) + ValueSerializer.serialize(prop, w) val extractedConstants = constantStore.getAll - val r = SigmaSerializer.startReader(byteWriter.toBytes) + val r = SigmaSerializer.startReader(w.toBytes) r.constantStore = new ConstantStore(extractedConstants) // deserialize value with placeholders val valueWithPlaceholders = ValueSerializer.deserialize(r).asSigmaProp - val header = (ErgoTree.ConstantSegregationHeader | headerFlags).toByte - new ErgoTree(header, extractedConstants, Right(valueWithPlaceholders)) + new ErgoTree( + header = setRequiredBits(setConstantSegregation(header)), + constants = extractedConstants, + root = Right(valueWithPlaceholders)) } - /** Create new ErgoTree for the given sigma proposition using default header and - * also performing constant segregation. - */ - def withSegregation(prop: SigmaPropValue): ErgoTree = - withSegregation(DefaultHeader, prop) - /** Deserializes an ErgoTree instance from a hexadecimal string. * * @param hex a hexadecimal string representing the serialized ErgoTree diff --git a/interpreter/shared/src/main/scala/sigmastate/eval/CostingDataContext.scala b/interpreter/shared/src/main/scala/sigmastate/eval/CostingDataContext.scala index 20ad8481bc..7e69c30eb1 100644 --- a/interpreter/shared/src/main/scala/sigmastate/eval/CostingDataContext.scala +++ b/interpreter/shared/src/main/scala/sigmastate/eval/CostingDataContext.scala @@ -75,7 +75,7 @@ case class CSigmaProp(sigmaTree: SigmaBoolean) extends SigmaProp with WrapperOf[ // the same serialization method is used in both cases // TODO v6.0: add `pk.propBytes(version)` (see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/903) val root = sigmaTree.toSigmaProp - val ergoTree = new ErgoTree(ErgoTree.DefaultHeader, EmptyConstants, Right(root), 0, null, None) + val ergoTree = new ErgoTree(ErgoTree.ZeroHeader, EmptyConstants, Right(root), 0, null, None) val bytes = DefaultSerializer.serializeErgoTree(ergoTree) Colls.fromArray(bytes) } diff --git a/interpreter/shared/src/main/scala/sigmastate/lang/SigmaPredef.scala b/interpreter/shared/src/main/scala/sigmastate/lang/SigmaPredef.scala index 74b1d45992..20b3a1534e 100644 --- a/interpreter/shared/src/main/scala/sigmastate/lang/SigmaPredef.scala +++ b/interpreter/shared/src/main/scala/sigmastate/lang/SigmaPredef.scala @@ -153,7 +153,7 @@ object SigmaPredef { { case (_, Seq(arg: EvaluatedValue[SString.type]@unchecked)) => ErgoAddressEncoder(networkPrefix).fromString(arg.value).get match { case a: P2PKAddress => SigmaPropConstant(a.pubkey) - case a@_ => sys.error(s"unsupported address $a") + case a => sys.error(s"unsupported address $a") } }), OperationInfo(Constant, "", diff --git a/interpreter/shared/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala b/interpreter/shared/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala index 85c0c77e04..6401f5bde3 100644 --- a/interpreter/shared/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala +++ b/interpreter/shared/src/main/scala/sigmastate/serialization/ErgoTreeSerializer.scala @@ -6,7 +6,7 @@ import sigmastate.Values.{Constant, ErgoTree, UnparsedErgoTree} import sigmastate.lang.DeserializationSigmaBuilder import sigmastate.lang.Terms.ValueOps import sigmastate.utils.{SigmaByteReader, SigmaByteWriter} -import sigmastate.Values.ErgoTree.EmptyConstants +import sigmastate.Values.ErgoTree.{EmptyConstants, HeaderType} import sigma.util.safeNewArray import sigmastate.utxo.ComplexityTable import debox.cfor @@ -14,8 +14,6 @@ import sigma.VersionContext import sigma.ast.SType import sigmastate.exceptions.{ReaderPositionLimitExceeded, SerializerException} -import java.util - /** * Rationale for soft-forkable ErgoTree serialization. * There are 2 points: @@ -203,8 +201,8 @@ class ErgoTreeSerializer { } /** Deserialize `header` and optional `size` slots only. */ - private def deserializeHeaderAndSize(r: SigmaByteReader): (Byte, Option[Int]) = { - val header = r.getByte() + private def deserializeHeaderAndSize(r: SigmaByteReader): (HeaderType, Option[Int]) = { + val header = HeaderType @@ r.getByte() CheckHeaderSizeBit(header) val sizeOpt = if (ErgoTree.hasSize(header)) { val size = r.getUInt().toInt @@ -231,7 +229,7 @@ class ErgoTreeSerializer { /** Deserialize constants section only. * HOTSPOT: don't beautify this code */ - private def deserializeConstants(header: Byte, r: SigmaByteReader): IndexedSeq[Constant[SType]] = { + private def deserializeConstants(header: HeaderType, r: SigmaByteReader): IndexedSeq[Constant[SType]] = { val constants: IndexedSeq[Constant[SType]] = if (ErgoTree.isConstantSegregation(header)) { val nConsts = r.getUInt().toInt @@ -255,7 +253,7 @@ class ErgoTreeSerializer { } /** Deserialize header and constant sections, but output the rest of the bytes as separate array. */ - def deserializeHeaderWithTreeBytes(r: SigmaByteReader): (Byte, Option[Int], IndexedSeq[Constant[SType]], Array[Byte]) = { + def deserializeHeaderWithTreeBytes(r: SigmaByteReader): (HeaderType, Option[Int], IndexedSeq[Constant[SType]], Array[Byte]) = { val (header, sizeOpt) = deserializeHeaderAndSize(r) val constants = deserializeConstants(header, r) val treeBytes = r.getBytes(r.remaining) diff --git a/interpreter/shared/src/test/scala/sigmastate/CrossVersionProps.scala b/interpreter/shared/src/test/scala/sigmastate/CrossVersionProps.scala index 0c4056dcee..67f54e151d 100644 --- a/interpreter/shared/src/test/scala/sigmastate/CrossVersionProps.scala +++ b/interpreter/shared/src/test/scala/sigmastate/CrossVersionProps.scala @@ -2,10 +2,12 @@ package sigmastate import debox.cfor import org.scalactic.source.Position + import scala.util.DynamicVariable import org.scalatest.Tag import sigmastate.eval.Profiler import org.scalatest.propspec.AnyPropSpecLike +import sigma.VersionContext trait CrossVersionProps extends AnyPropSpecLike with TestsBase { /** Number of times each test property is warmed up (i.e. executed before final execution). */ @@ -29,7 +31,9 @@ trait CrossVersionProps extends AnyPropSpecLike with TestsBase { System.gc() } forEachScriptAndErgoTreeVersion(activatedVersions, ergoTreeVersions) { - testFun_Run(testName, testFun) + VersionContext.withVersions(activatedVersionInTests, ergoTreeVersionInTests) { + testFun_Run(testName, testFun) + } } } } diff --git a/interpreter/shared/src/test/scala/sigmastate/TestsBase.scala b/interpreter/shared/src/test/scala/sigmastate/TestsBase.scala index 57ecd5e5e8..8d771a2404 100644 --- a/interpreter/shared/src/test/scala/sigmastate/TestsBase.scala +++ b/interpreter/shared/src/test/scala/sigmastate/TestsBase.scala @@ -4,6 +4,7 @@ import org.scalatest.matchers.should.Matchers import sigmastate.Values.{ErgoTree, SigmaBoolean, SigmaPropValue} import org.ergoplatform.ErgoTreePredef import sigma.VersionTesting +import sigmastate.Values.ErgoTree.{HeaderType, ZeroHeader} trait TestsBase extends Matchers with VersionTesting { /** Set this to true to enable debug console output in tests */ @@ -15,7 +16,7 @@ trait TestsBase extends Matchers with VersionTesting { /** Current ErgoTree header flags assigned dynamically using [[CrossVersionProps]] and * ergoTreeVersionInTests. */ - def ergoTreeHeaderInTests: Byte = ErgoTree.headerWithVersion(ergoTreeVersionInTests) + def ergoTreeHeaderInTests: HeaderType = ErgoTree.headerWithVersion(ZeroHeader, ergoTreeVersionInTests) /** Obtains [[ErgoTree]] which corresponds to True proposition using current * ergoTreeHeaderInTests. */ diff --git a/interpreter/shared/src/test/scala/sigmastate/crypto/SigningSpecification.scala b/interpreter/shared/src/test/scala/sigmastate/crypto/SigningSpecification.scala index 724a0171dc..6b41e7b986 100644 --- a/interpreter/shared/src/test/scala/sigmastate/crypto/SigningSpecification.scala +++ b/interpreter/shared/src/test/scala/sigmastate/crypto/SigningSpecification.scala @@ -2,13 +2,12 @@ package sigmastate.crypto import org.scalacheck.Gen import scorex.util.encode.Base16 -import sigmastate.{AtLeast, COR, CAND} -import sigmastate.Values.SigmaBoolean +import sigmastate.{AtLeast, CAND, COR} +import sigmastate.Values.{ErgoTree, SigmaBoolean} import sigmastate.crypto.DLogProtocol.DLogProverInput import sigmastate.helpers.{ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter, TestingCommons} -import sigmastate.interpreter.{HintsBag, ContextExtension, ProverResult} +import sigmastate.interpreter.{ContextExtension, HintsBag, ProverResult} import sigmastate.serialization.transformers.ProveDHTupleSerializer -import sigmastate.crypto.ProveDHTuple class SigningSpecification extends TestingCommons { @@ -24,7 +23,9 @@ class SigningSpecification extends TestingCommons { // check that signature is correct val verifier = new ErgoLikeTestInterpreter val proverResult = ProverResult(signature, ContextExtension.empty) - verifier.verify(sk.publicImage, fakeContext, proverResult, msg).get._1 shouldBe true + verifier.verify( + ErgoTree.fromSigmaBoolean(sk.publicImage), + fakeContext, proverResult, msg).get._1 shouldBe true // print one more random vector for debug purposes printSimpleSignature(msg: Array[Byte]) @@ -38,7 +39,7 @@ class SigningSpecification extends TestingCommons { // check that signature is correct val verifier = new ErgoLikeTestInterpreter val proverResult = ProverResult(signature, ContextExtension.empty) - verifier.verify(pdht, fakeContext, proverResult, msg).get._1 shouldBe true + verifier.verify(ErgoTree.fromSigmaBoolean(pdht), fakeContext, proverResult, msg).get._1 shouldBe true } property("handle improper signature") { @@ -59,7 +60,7 @@ class SigningSpecification extends TestingCommons { val verifier = new ErgoLikeTestInterpreter val proverResult = ProverResult(signature, ContextExtension.empty) val sigmaTree: SigmaBoolean = CAND(Seq(sk1.publicImage, sk2.publicImage)) - verifier.verify(sigmaTree, fakeContext, proverResult, msg).get._1 shouldBe true + verifier.verify(ErgoTree.fromSigmaBoolean(sigmaTree), fakeContext, proverResult, msg).get._1 shouldBe true } property("OR signature test vector") { @@ -71,7 +72,9 @@ class SigningSpecification extends TestingCommons { val verifier = new ErgoLikeTestInterpreter val proverResult = ProverResult(signature, ContextExtension.empty) val sigmaTree: SigmaBoolean = COR(Seq(sk1.publicImage, sk2.publicImage)) - verifier.verify(sigmaTree, fakeContext, proverResult, msg).get._1 shouldBe true + verifier.verify( + ErgoTree.fromSigmaBoolean(sigmaTree), + fakeContext, proverResult, msg).get._1 shouldBe true } property("OR with ProveDHT signature test vector") { @@ -84,7 +87,9 @@ class SigningSpecification extends TestingCommons { val verifier = new ErgoLikeTestInterpreter val proverResult = ProverResult(signature, ContextExtension.empty) val sigmaTree: SigmaBoolean = COR(Seq(sk1.publicImage, pdht)) - verifier.verify(sigmaTree, fakeContext, proverResult, msg).get._1 shouldBe true + verifier.verify( + ErgoTree.fromSigmaBoolean(sigmaTree), + fakeContext, proverResult, msg).get._1 shouldBe true } property("AND with OR signature test vector") { @@ -97,7 +102,9 @@ class SigningSpecification extends TestingCommons { val verifier = new ErgoLikeTestInterpreter val proverResult = ProverResult(signature, ContextExtension.empty) val sigmaTree: SigmaBoolean = CAND(Seq(sk1.publicImage, COR(Seq(sk2.publicImage, sk3.publicImage)))) - verifier.verify(sigmaTree, fakeContext, proverResult, msg).get._1 shouldBe true + verifier.verify( + ErgoTree.fromSigmaBoolean(sigmaTree), + fakeContext, proverResult, msg).get._1 shouldBe true } property("OR with AND signature test vector") { @@ -110,7 +117,9 @@ class SigningSpecification extends TestingCommons { val verifier = new ErgoLikeTestInterpreter val proverResult = ProverResult(signature, ContextExtension.empty) val sigmaTree: SigmaBoolean = COR(Seq(sk1.publicImage, CAND(Seq(sk2.publicImage, sk3.publicImage)))) - verifier.verify(sigmaTree, fakeContext, proverResult, msg).get._1 shouldBe true + verifier.verify( + ErgoTree.fromSigmaBoolean(sigmaTree), + fakeContext, proverResult, msg).get._1 shouldBe true } property("threshold signature test vector") { diff --git a/interpreter/shared/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala b/interpreter/shared/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala index 5943e8913b..a859ad9ada 100644 --- a/interpreter/shared/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala +++ b/interpreter/shared/src/test/scala/sigmastate/serialization/generators/ObjectGenerators.scala @@ -25,6 +25,7 @@ import sigmastate.utxo._ import sigma.Coll import sigma._ import sigma.ast._ +import sigmastate.Values.ErgoTree.ZeroHeader import java.math.BigInteger import scala.collection.compat.immutable.ArraySeq @@ -680,15 +681,15 @@ trait ObjectGenerators extends TypeGenerators sigmaBoolean <- Gen.delay(sigmaBooleanGen) propWithConstants <- Gen.delay(logicalExprTreeNodeGen(Seq(AND.apply, OR.apply, XorOf.apply)).map(_.toSigmaProp)) prop <- Gen.oneOf(propWithConstants, sigmaBoolean.toSigmaProp) - treeBuilder <- Gen.oneOf(Seq[SigmaPropValue => ErgoTree](ErgoTree.withSegregation, - ErgoTree.withoutSegregation)) + treeBuilder <- Gen.oneOf(Seq[SigmaPropValue => ErgoTree](ErgoTree.withSegregation(ZeroHeader, _), + ErgoTree.withoutSegregation(ZeroHeader, _))) } yield treeBuilder(prop) lazy val ergoTreeWithSegregationGen: Gen[ErgoTree] = for { sigmaBoolean <- Gen.delay(sigmaBooleanGen) propWithConstants <- Gen.delay(logicalExprTreeNodeGen(Seq(AND.apply, OR.apply, XorOf.apply)).map(_.toSigmaProp)) prop <- Gen.oneOf(propWithConstants, sigmaBoolean.toSigmaProp) - } yield ErgoTree.withSegregation(prop) + } yield ErgoTree.withSegregation(ZeroHeader, prop) def headerGen(stateRoot: AvlTree, parentId: Coll[Byte]): Gen[Header] = for { id <- modifierIdBytesGen diff --git a/interpreter/shared/src/test/scala/special/sigma/SigmaTestingData.scala b/interpreter/shared/src/test/scala/special/sigma/SigmaTestingData.scala index 979634f36c..fa0d9a4df9 100644 --- a/interpreter/shared/src/test/scala/special/sigma/SigmaTestingData.scala +++ b/interpreter/shared/src/test/scala/special/sigma/SigmaTestingData.scala @@ -24,6 +24,7 @@ import sigmastate.utils.Helpers import sigmastate._ import sigma.Coll import sigma.ast.{SBoolean, SSigmaProp} +import sigmastate.Values.ErgoTree.HeaderType import java.math.BigInteger import scala.reflect.ClassTag @@ -213,7 +214,7 @@ trait SigmaTestingData extends TestingCommons with ObjectGenerators { new ErgoBox( 9223372036854775807L, new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Array( SigmaPropConstant( CSigmaProp( @@ -251,7 +252,7 @@ trait SigmaTestingData extends TestingCommons with ObjectGenerators { new ErgoBox( 12345L, new ErgoTree( - 0.toByte, + HeaderType @@ 0.toByte, Vector(), Right( BoolToSigmaProp( diff --git a/sc/js/src/main/scala/sigmastate/lang/js/SigmaCompiler.scala b/sc/js/src/main/scala/sigmastate/lang/js/SigmaCompiler.scala index a624589396..3c90a3ee6a 100644 --- a/sc/js/src/main/scala/sigmastate/lang/js/SigmaCompiler.scala +++ b/sc/js/src/main/scala/sigmastate/lang/js/SigmaCompiler.scala @@ -7,6 +7,8 @@ import org.scalablytyped.runtime.StringDictionary import scala.scalajs.js import scala.scalajs.js.annotation.JSExportTopLevel import org.ergoplatform.sdk.js.{ErgoTree, Value} +import sigmastate.Values +import sigmastate.Values.ErgoTree.HeaderType import sigmastate.{STypeOps, Values} import sigmastate.eval.CompiletimeIRContext import sigmastate.lang.Terms.ValueOps @@ -27,7 +29,7 @@ class SigmaCompiler(_compiler: sigmastate.lang.SigmaCompiler) extends js.Object def compile( namedConstants: StringDictionary[Value], segregateConstants: Boolean, - additionalHeaderFlags: Byte, ergoScript: String): ErgoTree = { + treeHeader: Byte, ergoScript: String): ErgoTree = { val env = StringDictionary .wrapStringDictionary(namedConstants) .view.mapValues(v => isoValueToConstant.to(v)).toMap @@ -36,9 +38,9 @@ class SigmaCompiler(_compiler: sigmastate.lang.SigmaCompiler) extends js.Object require(prop.tpe.isSigmaProp, s"Expected SigmaProp expression type bue got ${prop.tpe}: $prop") val tree = if (segregateConstants) { - Values.ErgoTree.withSegregation(additionalHeaderFlags, prop.asSigmaProp) + Values.ErgoTree.withSegregation(HeaderType @@ treeHeader, prop.asSigmaProp) } else { - Values.ErgoTree.withoutSegregation(additionalHeaderFlags, prop.asSigmaProp) + Values.ErgoTree.withoutSegregation(HeaderType @@ treeHeader, prop.asSigmaProp) } new ErgoTree(tree) } diff --git a/sc/jvm/src/test/scala/sigmastate/helpers/SigmaPPrintSpec.scala b/sc/jvm/src/test/scala/sigmastate/helpers/SigmaPPrintSpec.scala index 895b0fbe53..12553d5e92 100644 --- a/sc/jvm/src/test/scala/sigmastate/helpers/SigmaPPrintSpec.scala +++ b/sc/jvm/src/test/scala/sigmastate/helpers/SigmaPPrintSpec.scala @@ -13,6 +13,7 @@ import sigmastate.serialization.OpCodes import sigmastate.utils.Helpers import sigmastate.utxo.SelectField import sigma.SigmaDslTesting +import sigmastate.Values.ErgoTree.HeaderType import sigma.ast._ import java.math.BigInteger @@ -89,7 +90,7 @@ class SigmaPPrintSpec extends SigmaDslTesting { |)""".stripMargin) test( new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Vector(IntArrayConstant(Array(10, 20))), Right(BoolToSigmaProp(TrueLeaf)) ), @@ -102,7 +103,7 @@ class SigmaPPrintSpec extends SigmaDslTesting { CostingBox( new ErgoBox( 9223372036854775807L, - new ErgoTree(0.toByte, Vector(), Right(BoolToSigmaProp(FalseLeaf))), + new ErgoTree(HeaderType @@ 0.toByte, Vector(), Right(BoolToSigmaProp(FalseLeaf))), Coll( (Digest32Coll @@ (ErgoAlgos.decodeUnsafe("6e789ab7b2fffff12280a6cd01557f6fb22b7f80ff7aff8e1f7f15973d7f0001").toColl), 10000000L) ), diff --git a/sc/shared/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala b/sc/shared/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala index f667753389..b2c8022286 100644 --- a/sc/shared/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala +++ b/sc/shared/src/test/scala/org/ergoplatform/ErgoAddressSpecification.scala @@ -22,6 +22,8 @@ import sigmastate.serialization.{GroupElementSerializer, ValueSerializer} import sigmastate.utils.Helpers._ import sigmastate.{CompilerCrossVersionProps, SigmaAnd} import sigma.SigmaDslTesting +import sigmastate.Values.ErgoTree.{ZeroHeader, setConstantSegregation} + import sigma.ast.SType import java.math.BigInteger @@ -81,7 +83,7 @@ class ErgoAddressSpecification extends SigmaDslTesting val p2s: Pay2SAddress = Pay2SAddress( ErgoTree.fromProposition( - ErgoTree.headerWithVersion(scriptVersion), + ErgoTree.headerWithVersion(ZeroHeader, scriptVersion), SigmaAnd(pk, pk10))) val p2sh: Pay2SHAddress = Pay2SHAddress(pk) val p2pk: P2PKAddress = P2PKAddress(pk) @@ -125,7 +127,7 @@ class ErgoAddressSpecification extends SigmaDslTesting val pk = dlogGroup.exponentiate(g, w) val pkBytes = GroupElementSerializer.toBytes(pk) val encoder = new ErgoAddressEncoder(MainnetNetworkPrefix) - val p2pk = new P2PKAddress(ProveDlog(pk), pkBytes)(encoder) + val p2pk = P2PKAddress(ProveDlog(pk))(encoder) val addrStr = p2pk.toString val prefix = (encoder.networkPrefix + P2PKAddress.addressTypePrefix).toByte @@ -148,6 +150,11 @@ class ErgoAddressSpecification extends SigmaDslTesting expectedP2S = "2MzJLjzX6UNfJHSVvioB6seYZ99FpWHB4Ds1gekHPv5KtNmLJUecgRWwvcGEqbt8ZAokUxGvKMuNgMZFzkPPdTGiYzPQoSR55NT5isCidMywgp52LYV", expectedP2SH = "qETVgcEctaXurNbFRgGUcZEGg4EKa8R4a5UNHY7", expectedP2PK = "3WwXpssaZwcNzaGMv3AgxBdTPJQBt5gCmqBsg3DykQ39bYdhJBsN") + + testFromProposition(scriptVersion = 2, + expectedP2S = "2N1Egpu5R9XtomV7x343LTXGrBLEkC8pvMVtjm6V3iHryxVfc6LUJhd1JsswhXMpPXUMatoBgnJ4qMGAC7dha27WkjqVBUsebWBDhig97zhmKS8T4YS", + expectedP2SH = "qETVgcEctaXurNbFRgGUcZEGg4EKa8R4a5UNHY7", + expectedP2PK = "3WwXpssaZwcNzaGMv3AgxBdTPJQBt5gCmqBsg3DykQ39bYdhJBsN") } property("decode with wrong address") { @@ -192,7 +199,7 @@ class ErgoAddressSpecification extends SigmaDslTesting { val unparsedTree = new ErgoTree( - (ErgoTree.ConstantSegregationHeader | ergoTreeHeaderInTests).toByte, + setConstantSegregation(ergoTreeHeaderInTests), Array[Constant[SType]](), Left(UnparsedErgoTree(Array[Byte](), ValidationException("", ValidationRules.CheckTypeCode, Seq()))) ) @@ -204,7 +211,7 @@ class ErgoAddressSpecification extends SigmaDslTesting { val invalidTree = new ErgoTree( - (ErgoTree.ConstantSegregationHeader | ergoTreeHeaderInTests).toByte, + setConstantSegregation(ergoTreeHeaderInTests), Array[Constant[SType]](), Right(IntConstant(10).asSigmaProp) ) @@ -280,16 +287,17 @@ class ErgoAddressSpecification extends SigmaDslTesting // when everything is ok testPay2SHAddress(addr, script = scriptVarId -> ByteArrayConstant(scriptBytes)) + val expectedCost = if (ergoTreeVersionInTests == 0) 88 else 90 // account for size serialized for version > 0 + // when limit is low { val deliberatelySmallLimit = 24 - assertExceptionThrown( testPay2SHAddress(addr, script = scriptVarId -> ByteArrayConstant(scriptBytes), costLimit = deliberatelySmallLimit), rootCauseLike[CostLimitException]( - s"Estimated execution cost 88 exceeds the limit $deliberatelySmallLimit") + s"Estimated execution cost $expectedCost exceeds the limit $deliberatelySmallLimit") ) } @@ -305,7 +313,7 @@ class ErgoAddressSpecification extends SigmaDslTesting costLimit = deliberatelySmallLimit) }, rootCauseLike[CostLimitException]( - s"Estimated execution cost 88 exceeds the limit $deliberatelySmallLimit") + s"Estimated execution cost $expectedCost exceeds the limit $deliberatelySmallLimit") ) } diff --git a/sc/shared/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala b/sc/shared/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala index 7f66d3f7d6..931a532188 100644 --- a/sc/shared/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala +++ b/sc/shared/src/test/scala/org/ergoplatform/ErgoLikeTransactionSpec.scala @@ -25,7 +25,7 @@ class ErgoLikeTransactionSpec extends SigmaDslTesting { val token2 = "a3ff007f00057600808001ff8f8000019000ffdb806fff7cc0b6015eb37fa600" val b1 = new ErgoBoxCandidate( 10L, - ErgoTree(ErgoTree.DefaultHeader, Vector(), TrueSigmaProp), + ErgoTree(ErgoTree.ZeroHeader, Vector(), TrueSigmaProp), 100, Coll( (Digest32Coll @@@ (ErgoAlgos.decodeUnsafe(token1).toColl)) -> 10000000L, @@ -34,7 +34,7 @@ class ErgoLikeTransactionSpec extends SigmaDslTesting { ) val b1_clone = new ErgoBoxCandidate( 10L, - ErgoTree(ErgoTree.DefaultHeader, Vector(), TrueSigmaProp), + ErgoTree(ErgoTree.ZeroHeader, Vector(), TrueSigmaProp), 100, Coll( Digest32Coll @@ (ErgoAlgos.decodeUnsafe(token1).toColl) -> 10000000L, diff --git a/sc/shared/src/test/scala/org/ergoplatform/ErgoTreePredefSpec.scala b/sc/shared/src/test/scala/org/ergoplatform/ErgoTreePredefSpec.scala index 33a0eb1d89..e147be0c04 100644 --- a/sc/shared/src/test/scala/org/ergoplatform/ErgoTreePredefSpec.scala +++ b/sc/shared/src/test/scala/org/ergoplatform/ErgoTreePredefSpec.scala @@ -93,7 +93,9 @@ class ErgoTreePredefSpec extends CompilerTestingCommons with CompilerCrossVersio // unable to satisfy R4 conditions checkSpending(remaining(height), height, prop, R4Prop(false)).isFailure shouldBe true // incorrect new script - checkSpending(remaining(height), height, TrivialProp.TrueProp, R4Prop(true)).isFailure shouldBe true + checkSpending(remaining(height), height, + ErgoTree.fromProposition(TrivialProp.TrueProp), + R4Prop(true)).isFailure shouldBe true // collect less coins then possible checkSpending(remaining(height) + 1, height, prop, R4Prop(true)).isSuccess shouldBe true // collect more coins then possible @@ -189,7 +191,8 @@ class ErgoTreePredefSpec extends CompilerTestingCommons with CompilerCrossVersio createRewardTx(currentRate, height, correctProp).isSuccess shouldBe true createRewardTx(currentRate, height, incorrectDelay).isFailure shouldBe true createRewardTx(currentRate, height, incorrectPk).isFailure shouldBe true - createRewardTx(currentRate, height, minerPk).isFailure shouldBe true + createRewardTx(currentRate, height, + ErgoTree.fromSigmaBoolean(minerPk)).isFailure shouldBe true } def createRewardTx(emissionAmount: Long, nextHeight: Int, minerProp: ErgoTree): Try[ErgoLikeTransaction] = { diff --git a/sc/shared/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala b/sc/shared/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala index 5a17f01448..7fddd42e12 100644 --- a/sc/shared/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala +++ b/sc/shared/src/test/scala/org/ergoplatform/dsl/TestContractSpec.scala @@ -17,20 +17,24 @@ import sigmastate.AvlTreeData import sigmastate.Values.{ErgoTree, EvaluatedValue} import sigmastate.eval.{CSigmaProp, IRContext, CAnyValue} import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, CompilerTestingCommons} +import sigmastate.eval.{CAnyValue, CSigmaProp, IRContext} +import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.lang.Terms.ValueOps import sigma.{AnyValue, Evaluation, SigmaProp} +import sigma.{AnyValue, SigmaProp} +import sigmastate.Values.ErgoTree.ZeroHeader case class TestContractSpec(testSuite: CompilerTestingCommons)(implicit val IR: IRContext) extends ContractSpec { case class TestPropositionSpec(name: String, dslSpec: Proposition, scriptSpec: ErgoScript) extends PropositionSpec { lazy val ergoTree: ErgoTree = { val value = testSuite.compile(scriptSpec.env, scriptSpec.code) - val headerFlags = scriptSpec.scriptVersion match { - case Some(version) => ErgoTree.headerWithVersion(version) + val header = scriptSpec.scriptVersion match { + case Some(version) => ErgoTree.headerWithVersion(ZeroHeader, version) case None => testSuite.ergoTreeHeaderInTests } - val tree: ErgoTree = ErgoTree.fromProposition(headerFlags, value.asSigmaProp) + val tree: ErgoTree = ErgoTree.fromProposition(header, value.asSigmaProp) tree } } diff --git a/sc/shared/src/test/scala/sigma/SigmaDslSpecification.scala b/sc/shared/src/test/scala/sigma/SigmaDslSpecification.scala index af14fca2a9..d250bb5086 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslSpecification.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslSpecification.scala @@ -1,49 +1,49 @@ package special.sigma -import java.math.BigInteger +import org.ergoplatform.ErgoBox.AdditionalRegisters import org.ergoplatform._ import org.ergoplatform.settings.ErgoAlgos +import org.scalacheck.Arbitrary._ import org.scalacheck.{Arbitrary, Gen} import sigma.data.{CBigInt, ExactIntegral, ExactNumeric, ExactOrdering, RType} +import org.scalatest.BeforeAndAfterAll import scorex.crypto.authds.avltree.batch._ import scorex.crypto.authds.{ADKey, ADValue} import scorex.crypto.hash.{Blake2b256, Digest32} +import scorex.util.ModifierId +import sigma.Extensions._ +import sigma.{VersionContext, _} +import sigma.data.RType._ +import sigma.data.{ExactIntegral, ExactNumeric, ExactOrdering, RType} import sigma.util.Extensions._ import sigmastate.utils.Extensions._ import sigma.ast.SCollection._ import sigmastate.Values.IntConstant +import sigmastate.Values.ErgoTree.{HeaderType, ZeroHeader} +import sigmastate.Values.{IntConstant, _} import sigmastate._ import sigmastate.crypto.DLogProtocol._ -import sigmastate.Values._ -import sigmastate.lang.Terms.Apply +import sigmastate.crypto.ProveDHTuple import sigmastate.eval.Extensions._ +import sigmastate.eval.OrderingOps._ import sigmastate.eval._ import sigmastate.lang.Terms.{MethodCall, PropertyCall} import sigmastate.utxo._ import sigma._ import sigma.Extensions._ -import sigmastate.utils.Helpers -import sigmastate.utils.Helpers._ +import sigma.ast.{SAvlTree, SBigInt, SBoolean, SBox, SByte, SCollection, SCollectionType, SContext, SGroupElement, SHeader, SInt, SLong, SOption, SPair, SShort, SSigmaProp, STuple, SType, STypeVar} import sigmastate.helpers.TestingHelpers._ - -import scala.util.{Failure, Success, Try} -import OrderingOps._ -import org.ergoplatform.ErgoBox.AdditionalRegisters -import org.scalacheck.Arbitrary._ -import org.scalacheck.Gen.frequency -import org.scalatest.{BeforeAndAfterAll, Tag} -import sigma.data.RType._ -import scorex.util.ModifierId -import sigmastate.crypto.ProveDHTuple import sigmastate.interpreter._ -import org.scalactic.source.Position -import sigma.VersionContext -import sigma.ast._ -import sigmastate.helpers.SigmaPPrint -import sigmastate.exceptions.GraphBuildingException +import sigmastate.lang.Terms.{Apply, MethodCall, PropertyCall} import sigmastate.serialization.ValueCodes.OpCode +import sigmastate.utils.Extensions._ +import sigmastate.utils.Helpers +import sigmastate.utils.Helpers._ +import sigmastate.utxo._ +import java.math.BigInteger import scala.collection.compat.immutable.ArraySeq +import scala.util.{Failure, Success} /** This suite tests every method of every SigmaDsl type to be equivalent to * the evaluation of the corresponding ErgoScript operation. @@ -4613,7 +4613,7 @@ class SigmaDslSpecification extends SigmaDslTesting new ErgoBox( 80946L, new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Vector( SigmaPropConstant( CSigmaProp( @@ -4643,7 +4643,7 @@ class SigmaDslSpecification extends SigmaDslTesting new ErgoBox( -1L, new ErgoTree( - 0.toByte, + HeaderType @@ 0.toByte, Vector(), Right(SigmaPropConstant(CSigmaProp(ProveDlog(Helpers.decodeECPoint("02af645874c3b53465a5e9d820eb207d6001258c3b708f0d31d7c2e342833dce64"))))) ), @@ -4709,7 +4709,7 @@ class SigmaDslSpecification extends SigmaDslTesting new ErgoBox( 1000000L, new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Vector( SigmaPropConstant( CSigmaProp( @@ -4746,7 +4746,7 @@ class SigmaDslSpecification extends SigmaDslTesting new ErgoBox( 2769336982721999022L, new ErgoTree( - 0.toByte, + HeaderType @@ 0.toByte, Vector(), Right(SigmaPropConstant(CSigmaProp(ProveDlog(Helpers.decodeECPoint("02d13e1a8c31f32194761adc1cdcbaa746b3e049e682bba9308d8ee84576172991"))))) ), @@ -6578,7 +6578,7 @@ class SigmaDslSpecification extends SigmaDslTesting new ErgoBox( 1L, new ErgoTree( - 0.toByte, + HeaderType @@ 0.toByte, Vector(), Right( SigmaPropConstant( @@ -6614,7 +6614,7 @@ class SigmaDslSpecification extends SigmaDslTesting new ErgoBox( 1000000000L, new ErgoTree( - 0.toByte, + HeaderType @@ 0.toByte, Vector(), Right(BoolToSigmaProp(OR(ConcreteCollection(Array(FalseLeaf, AND(ConcreteCollection(Array(FalseLeaf, FalseLeaf), SBoolean))), SBoolean)))) ), @@ -9655,14 +9655,14 @@ class SigmaDslSpecification extends SigmaDslTesting property("substConstants equivalence") { // tree without constant segregation - val t1 = ErgoTree(ErgoTree.DefaultHeader, Vector(), TrueSigmaProp) + val t1 = ErgoTree(ErgoTree.ZeroHeader, Vector(), TrueSigmaProp) // tree with constant segregation, but without constants - val t2 = ErgoTree(ErgoTree.ConstantSegregationHeader, Vector(), TrueSigmaProp) + val t2 = ErgoTree(ErgoTree.setConstantSegregation(ZeroHeader), Vector(), TrueSigmaProp) // tree with one segregated constant - val t3 = ErgoTree(ErgoTree.ConstantSegregationHeader, Vector(TrueSigmaProp), ConstantPlaceholder(0, SSigmaProp)) + val t3 = ErgoTree(ErgoTree.setConstantSegregation(ZeroHeader), Vector(TrueSigmaProp), ConstantPlaceholder(0, SSigmaProp)) // tree with one segregated constant of different type val t4 = ErgoTree( - ErgoTree.ConstantSegregationHeader, + ErgoTree.setConstantSegregation(ZeroHeader), Vector(IntConstant(10)), BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), IntConstant(20)))) def costDetails(i: Int) = TracedCost( diff --git a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala index f7f276727c..508fdd361f 100644 --- a/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala +++ b/sc/shared/src/test/scala/sigma/SigmaDslTesting.scala @@ -18,6 +18,7 @@ import sigma.util.BenchmarkUtil import sigma.util.CollectionUtil._ import sigma.util.Extensions._ import sigma.util.StringUtil.StringUtilExtensions +import sigmastate.Values.ErgoTree.ZeroHeader import sigma.ast.SType.AnyOps import sigmastate.Values.{ByteArrayConstant, Constant, ConstantNode, ErgoTree, IntConstant, SValue} import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog} @@ -325,7 +326,7 @@ class SigmaDslTesting extends AnyPropSpec pkAlice, DeserializeRegister(ErgoBox.R5, SSigmaProp), // deserialize pkBob DeserializeContext(2, SSigmaProp))) // deserialize pkCarol - val header = ErgoTree.headerWithVersion(ergoTreeVersionInTests) + val header = ErgoTree.headerWithVersion(ZeroHeader, ergoTreeVersionInTests) ErgoTree.withSegregation(header, sigmastate.SigmaOr(prop, multisig)) } diff --git a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala index 61445216b1..9818c112cd 100644 --- a/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/ErgoTreeSpecification.scala @@ -22,6 +22,7 @@ import sigmastate.utxo._ import sigma._ import sigma.ast._ import sigma.{ContractsTestkit, SigmaDslTesting} +import sigmastate.Values.ErgoTree.HeaderType import sigmastate.SCollectionMethods.checkValidFlatmap @@ -61,13 +62,13 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { property("ErgoTree.toProposition") { val t1 = new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Array(IntConstant(1)), Right(BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), IntConstant(1)))) ) val t = new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Array(IntConstant(1)), Left(UnparsedErgoTree(t1.bytes, ValidationException("", ValidationRules.CheckTypeCode, Seq()))) ) @@ -80,7 +81,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { property("ErgoTree.template") { { val t = new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Array(IntConstant(1)), Right(BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), IntConstant(1)))) ) @@ -95,7 +96,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { property("ErgoTree.bytes") { val t = new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Array(IntConstant(1)), Right(BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), IntConstant(1)))) ) @@ -113,7 +114,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { Value.hasDeserialize(EQ(const, dc)) shouldBe true Value.hasDeserialize(Plus(Plus(const, dc), dr)) shouldBe true val t = new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Array(IntConstant(1)), Right(BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), IntConstant(1)))) ) @@ -123,7 +124,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { property("ErgoTree.hasDeserialize") { { val t = new ErgoTree( - 0.toByte, + HeaderType @@ 0.toByte, Array[Constant[SType]](), Right(TrueSigmaProp)) t._hasDeserialize shouldBe None @@ -132,7 +133,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { { val t = new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Array(IntConstant(1)), Right(BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), DeserializeContext(1.toByte, SInt)))) ) @@ -143,13 +144,13 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { property("ErgoTree equality") { val t1 = new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Array(IntConstant(1)), Right(BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), IntConstant(1)))) ) - val t2 = new ErgoTree(16.toByte, Array(IntConstant(1)), Right(TrueSigmaProp)) - val t3 = new ErgoTree(16.toByte, Array(IntConstant(1)), Right(TrueSigmaProp)) - val t4 = new ErgoTree(16.toByte, Vector(), Right(TrueSigmaProp)) + val t2 = new ErgoTree(HeaderType @@ 16.toByte, Array(IntConstant(1)), Right(TrueSigmaProp)) + val t3 = new ErgoTree(HeaderType @@ 16.toByte, Array(IntConstant(1)), Right(TrueSigmaProp)) + val t4 = new ErgoTree(HeaderType @@ 16.toByte, Vector(), Right(TrueSigmaProp)) val t5 = new ErgoTree(ErgoTree.DefaultHeader, Vector(), Right(TrueSigmaProp)) assert(t1 != t2) assert(t2 == t3) @@ -683,7 +684,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { val addr = ErgoAddressEncoder.Mainnet.fromString("Fo6oijFP2JM87ac7w").getOrThrow val tree = addr.script tree shouldBe new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Vector(TrueLeaf), Right(BoolToSigmaProp(BoolToSigmaProp(ConstantPlaceholder(0, SBoolean)).asBoolValue)) ) @@ -719,7 +720,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { val addr = ErgoAddressEncoder.Mainnet.fromString("Fo6oijFP2JM87ac7w").getOrThrow val tree = addr.script tree shouldBe new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Vector(TrueLeaf), Right(BoolToSigmaProp(BoolToSigmaProp(ConstantPlaceholder(0, SBoolean)).asBoolValue)) ) @@ -751,7 +752,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit { // 4503b5d77cb74b4354771b835cd61e9d5257022a8efff0fddfac249e0c25b492 val addr = ErgoAddressEncoder.Mainnet.fromString("28JURWHTHwTnXJt5F38").getOrThrow val tree = addr.script - tree shouldBe new ErgoTree(16.toByte, Vector(), + tree shouldBe new ErgoTree(HeaderType @@ 16.toByte, Vector(), Right(BoolToSigmaProp( CreateProveDlog(OptionGet(ExtractRegisterAs(Self, ErgoBox.R4, SOption(SGroupElement)))).asBoolValue) )) diff --git a/sc/shared/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala b/sc/shared/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala index 77a18188c1..8b2a35c8ea 100644 --- a/sc/shared/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/ScriptVersionSwitchSpecification.scala @@ -3,20 +3,21 @@ package sigmastate import org.ergoplatform.ErgoBox.AdditionalRegisters import org.ergoplatform._ import scorex.util.ModifierId -import sigmastate.Values.ErgoTree.{DefaultHeader, updateVersionBits} +import sigma.VersionContext.MaxSupportedScriptVersion +import sigma.{Box, SigmaDslTesting} +import sigmastate.Values.ErgoTree.{HeaderType, ZeroHeader, setConstantSegregation, setVersionBits} import sigmastate.Values._ import sigma.VersionContext.MaxSupportedScriptVersion import sigma.ast.{SBoolean, SBox, SCollection, SType} import sigmastate.eval._ import sigmastate.exceptions.InterpreterException -import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers.createBox +import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.interpreter.ErgoTreeEvaluator.DefaultEvalSettings import sigmastate.interpreter.EvalSettings.EvaluationMode -import sigmastate.interpreter.{CostedProverResult, ErgoTreeEvaluator, EvalSettings, Interpreter, ProverResult} +import sigmastate.interpreter._ import sigmastate.lang.Terms.ValueOps import sigmastate.utils.Helpers._ -import sigma.{Box, SigmaDslTesting} /** Specification to verify that the interpreter behaves according to docs/aot-jit-switch.md. * @@ -36,7 +37,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { new ErgoBox( 1L, new ErgoTree( - 0.toByte, + HeaderType @@ 0.toByte, Vector(), Right(BoolToSigmaProp(OR(ConcreteCollection(Array(FalseLeaf, AND(ConcreteCollection(Array(FalseLeaf, FalseLeaf), SBoolean))), SBoolean)))) ), @@ -49,7 +50,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { ) /** Creates ErgoTree with segregated constants and also the given header flags. */ - def createErgoTree(headerFlags: Byte)(implicit IR: IRContext): ErgoTree = { + def createErgoTree(header: HeaderType)(implicit IR: IRContext): ErgoTree = { val code = s"""{ | val func = { (x: Coll[Box]) => x.filter({(b: Box) => b.value > 1 }) } @@ -66,7 +67,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { checkCompilerResult(res) res.buildTree.asSigmaProp } - ErgoTree.withSegregation(headerFlags, compiledTree) + ErgoTree.withSegregation(header, compiledTree) } /** Proves the given ergoTree in a dummy context with the given activatedScriptVersion. @@ -137,7 +138,10 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { property("new versions of scripts will require size bit in the header") { (1 to 7).foreach { version => assertExceptionThrown( - createErgoTree(headerFlags = updateVersionBits(DefaultHeader, version.toByte)), + { + val tree = createErgoTree(header = setVersionBits(ZeroHeader, version.toByte)) + new ErgoTree(setVersionBits(setConstantSegregation(ZeroHeader), version.toByte), tree.constants, tree.root) + }, exceptionLike[IllegalArgumentException]("For newer version the size bit is required") ) } @@ -161,7 +165,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { forEachErgoTreeVersion(treeVers) { // SF inactive: check cost vectors of v4.x interpreter - val headerFlags = ErgoTree.headerWithVersion(ergoTreeVersionInTests) + val headerFlags = ErgoTree.defaultHeaderWithVersion(ergoTreeVersionInTests) val ergoTree = createErgoTree(headerFlags) // both prove and verify are accepting with full evaluation @@ -188,8 +192,8 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { forEachActivatedScriptVersion(Array[Byte](0, 1)) { // Block Versions 1, 2 forEachErgoTreeVersion(ergoTreeVers = Array[Byte](2)) { // only Script v2 - val headerFlags = ErgoTree.headerWithVersion(ergoTreeVersionInTests /* Script v2 */) - val ergoTree = createErgoTree(headerFlags = headerFlags) + val header = ErgoTree.headerWithVersion(ZeroHeader, ergoTreeVersionInTests /* Script v2 */) + val ergoTree = createErgoTree(header) // prover is rejecting ErgoTree versions higher than activated assertExceptionThrown( @@ -247,7 +251,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { forEachActivatedScriptVersion(activatedVers = Array[Byte](2)) // version for Block v3 { forEachErgoTreeVersion(ergoTreeVers = Array[Byte](3, 4)) { // scripts >= v3 - val headerFlags = ErgoTree.headerWithVersion(ergoTreeVersionInTests) + val headerFlags = ErgoTree.defaultHeaderWithVersion(ergoTreeVersionInTests) val ergoTree = createErgoTree(headerFlags) // prover is rejecting ErgoTree versions higher than activated @@ -274,7 +278,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { forEachActivatedScriptVersion(activatedVers = Array[Byte](3)) // version for Block v4 { forEachErgoTreeVersion(ergoTreeVers = Array[Byte](3, 4)) { // scripts >= v3 - val headerFlags = ErgoTree.headerWithVersion(ergoTreeVersionInTests) + val headerFlags = ErgoTree.defaultHeaderWithVersion(ergoTreeVersionInTests) val ergoTree = createErgoTree(headerFlags) // prover is rejecting, because such context parameters doesn't make sense @@ -306,7 +310,7 @@ class ScriptVersionSwitchSpecification extends SigmaDslTesting { { forEachErgoTreeVersion(Array[Byte](0, 1, 2)) { // tree versions supported by v5.x // SF inactive: check cost vectors of v4.x interpreter - val headerFlags = ErgoTree.headerWithVersion(ergoTreeVersionInTests) + val headerFlags = ErgoTree.defaultHeaderWithVersion(ergoTreeVersionInTests) val ergoTree = createErgoTree(headerFlags) // both prove and verify are accepting with full evaluation diff --git a/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala b/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala index b5680ec507..7caf38d5f4 100644 --- a/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/SoftForkabilitySpecification.scala @@ -4,9 +4,10 @@ import org.ergoplatform._ import org.ergoplatform.validation.ValidationRules._ import org.ergoplatform.validation._ import org.scalatest.BeforeAndAfterAll -import sigma.ast.{SBoolean, SCollection, SContext, SFunc, SGlobal, SInt} import sigma.ast.SPrimType.MaxPrimTypeCode -import sigmastate.Values.ErgoTree.EmptyConstants +import sigma.ast._ +import sigma.{Colls, SigmaTestingData} +import sigmastate.Values.ErgoTree.{EmptyConstants, HeaderType, ZeroHeader, setSizeBit} import sigmastate.Values.{ByteArrayConstant, ErgoTree, IntConstant, NotReadyValueInt, UnparsedErgoTree, ValueCompanion} import sigmastate.exceptions.{InterpreterException, SerializerException} import sigmastate.helpers.TestingHelpers._ @@ -15,13 +16,11 @@ import sigmastate.interpreter.ErgoTreeEvaluator.DataEnv import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.interpreter.{ContextExtension, ErgoTreeEvaluator, ProverResult} import sigmastate.lang.Terms._ -import sigmastate.serialization.ValueCodes.LastConstantCode import sigmastate.serialization.SigmaSerializer.startReader +import sigmastate.serialization.ValueCodes.{LastConstantCode, OpCode} import sigmastate.serialization._ import sigmastate.utils.Helpers._ import sigmastate.utxo.DeserializeContext -import sigma.{Colls, SigmaTestingData} -import sigmastate.serialization.ValueCodes.OpCode class SoftForkabilitySpecification extends SigmaTestingData with CompilerTestingCommons @@ -41,7 +40,7 @@ class SoftForkabilitySpecification extends SigmaTestingData // cast Boolean typed prop to SigmaProp (which is invalid) // ErgoTree v0 lazy val invalidPropV1: ErgoTree = ErgoTree.fromProposition( - ErgoTree.headerWithVersion(0), + ErgoTree.headerWithVersion(ZeroHeader, 0), booleanPropV1.asSigmaProp) lazy val invalidTxV1 = createTransaction(createBox(boxAmt, invalidPropV1, 1)) @@ -50,7 +49,7 @@ class SoftForkabilitySpecification extends SigmaTestingData lazy val propV1 = booleanPropV1.toSigmaProp lazy val txV1 = createTransaction( createBox(boxAmt, - ErgoTree.fromProposition(ErgoTree.headerWithVersion(0), propV1), // ErgoTree v0 + ErgoTree.fromProposition(ErgoTree.headerWithVersion(ZeroHeader, 0), propV1), // ErgoTree v0 1)) lazy val txV1bytes = txV1.messageToSign @@ -133,7 +132,7 @@ class SoftForkabilitySpecification extends SigmaTestingData lazy val booleanPropV2 = GT(Height2, IntConstant(deadline)) lazy val invalidPropV2: ErgoTree = ErgoTree.fromProposition( - headerFlags = ErgoTree.headerWithVersion(0), // ErgoTree v0 + header = ErgoTree.headerWithVersion(ZeroHeader, 0), // ErgoTree v0 prop = booleanPropV2.asSigmaProp) lazy val invalidTxV2 = createTransaction(createBox(boxAmt, invalidPropV2, 1)) @@ -141,7 +140,7 @@ class SoftForkabilitySpecification extends SigmaTestingData lazy val propV2 = booleanPropV2.toSigmaProp // prepare bytes using special serialization WITH `size flag` in the header - lazy val propV2tree = ErgoTree.withSegregation(ErgoTree.SizeFlag, propV2) + lazy val propV2tree = ErgoTree.withSegregation(setSizeBit(ZeroHeader), propV2) lazy val propV2treeBytes = runOnV2Node { propV2tree.bytes } @@ -156,7 +155,7 @@ class SoftForkabilitySpecification extends SigmaTestingData property("node v1, soft-fork up to v2, script v2 without size bit") { // try prepare v2 script without `size bit` in the header assertExceptionThrown({ - ErgoTree(1.toByte, EmptyConstants, propV2) + new ErgoTree(HeaderType @@ 1.toByte, EmptyConstants, Right(propV2)) }, { case _: IllegalArgumentException => true case _ => false @@ -165,7 +164,7 @@ class SoftForkabilitySpecification extends SigmaTestingData // prepare bytes using default serialization and then replacing version in the header val v2tree_withoutSize_bytes = runOnV2Node { val tree = ErgoTree.fromProposition( - ErgoTree.headerWithVersion(0), propV2) // ErgoTree v0 + ErgoTree.headerWithVersion(ZeroHeader, 0), propV2) // ErgoTree v0 val bytes = tree.bytes // set version to v2 while not setting the size bit, // we cannot do this using ErgoTree constructor (due to require() check) @@ -270,7 +269,7 @@ class SoftForkabilitySpecification extends SigmaTestingData // v1 main script which deserializes v2 script from context val mainProp = BinAnd(GT(Height, IntConstant(deadline)), DeserializeContext(1, SBoolean)).toSigmaProp val mainTree = ErgoTree.fromProposition( - headerFlags = ErgoTree.headerWithVersion(0), // ErgoTree v0 + header = ErgoTree.headerWithVersion(ZeroHeader, 0), // ErgoTree v0 prop = mainProp) val tx = createTransaction(createBox(boxAmt, mainTree, 1)) diff --git a/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala b/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala index 7be159757c..eb39ace24b 100644 --- a/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala +++ b/sc/shared/src/test/scala/sigmastate/eval/ErgoScriptTestkit.scala @@ -5,6 +5,7 @@ import org.ergoplatform.validation.ValidationSpecification import org.ergoplatform.{Context => _, _} import scalan.BaseCtxTests import sigma.VersionContext +import sigmastate.Values.{BigIntArrayConstant, ErgoTree, EvaluatedValue, SValue, SigmaPropConstant, Value} import sigma.ast.SType import sigmastate.Values.{BigIntArrayConstant, EvaluatedValue, SValue, SigmaPropConstant, Value} import sigmastate.helpers.TestingHelpers._ @@ -68,8 +69,8 @@ trait ErgoScriptTestkit extends ContractsTestkit with LangTests lazy val boxToSpend = testBox(10, TrueTree, 0, additionalRegisters = Map(ErgoBox.R4 -> BigIntArrayConstant(bigIntegerArr1))) - lazy val tx1Output1 = testBox(minToRaise, projectPubKey, 0) - lazy val tx1Output2 = testBox(1, projectPubKey, 0) + lazy val tx1Output1 = testBox(minToRaise, ErgoTree.fromProposition(projectPubKey), 0) + lazy val tx1Output2 = testBox(1, ErgoTree.fromProposition(projectPubKey), 0) lazy val tx1 = new ErgoLikeTransaction(IndexedSeq(), IndexedSeq(), IndexedSeq(tx1Output1, tx1Output2)) lazy val ergoCtx = ErgoLikeContextTesting( currentHeight = timeout - 1, diff --git a/sc/shared/src/test/scala/sigmastate/eval/EvaluationTest.scala b/sc/shared/src/test/scala/sigmastate/eval/EvaluationTest.scala index c2d6143748..7c38f2e60a 100644 --- a/sc/shared/src/test/scala/sigmastate/eval/EvaluationTest.scala +++ b/sc/shared/src/test/scala/sigmastate/eval/EvaluationTest.scala @@ -1,7 +1,7 @@ package sigmastate.eval import org.ergoplatform.ErgoBox -import sigmastate.Values.{ConcreteCollection, IntArrayConstant, IntConstant, SigmaPropConstant, SigmaPropValue} +import sigmastate.Values.{ConcreteCollection, ErgoTree, IntArrayConstant, IntConstant, SigmaPropConstant, SigmaPropValue} import sigmastate.helpers.ContextEnrichingTestProvingInterpreter import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ @@ -39,7 +39,7 @@ class EvaluationTest extends BaseCtxTests test("lazy logical ops") { val prover = new ContextEnrichingTestProvingInterpreter val pk = prover.dlogSecrets.head.publicImage - val self = testBox(1, pk, 0, additionalRegisters = Map(ErgoBox.R4 -> IntConstant(10))) + val self = testBox(1, ErgoTree.fromSigmaBoolean(pk), 0, additionalRegisters = Map(ErgoBox.R4 -> IntConstant(10))) val ctx = newErgoContext(height = 1, self) // guarded register access: existing reg reduce(emptyEnv, "lazy1", "SELF.R4[Int].isDefined && SELF.R4[Int].get == 10", ctx, true) diff --git a/sc/shared/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala b/sc/shared/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala index 2ccabd953a..24c2991404 100644 --- a/sc/shared/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/serialization/ErgoTreeSerializerSpecification.scala @@ -1,11 +1,11 @@ package sigmastate.serialization -import java.math.BigInteger import org.ergoplatform.ErgoBox import org.ergoplatform.validation.ValidationException import org.ergoplatform.validation.ValidationRules.CheckDeserializedScriptIsSigmaProp import sigma.ast.SInt import sigma.data.CBigInt +import sigmastate.Values.ErgoTree.HeaderType import sigmastate.Values.{BigIntConstant, ByteConstant, ConstantPlaceholder, ErgoTree, IntConstant, ShortConstant, SigmaPropValue, UnparsedErgoTree} import sigmastate._ import sigmastate.eval.IRContext @@ -14,6 +14,8 @@ import sigmastate.helpers.CompilerTestingCommons import sigmastate.serialization.ErgoTreeSerializer.DefaultSerializer import sigmastate.utxo.{DeserializeContext, DeserializeRegister} +import java.math.BigInteger + class ErgoTreeSerializerSpecification extends SerializationSpecification with CompilerTestingCommons with CompilerCrossVersionProps { @@ -34,7 +36,7 @@ class ErgoTreeSerializerSpecification extends SerializationSpecification Seq(ErgoTree(ergoTreeHeaderInTests, constants, outExpr)) } else { Seq( - ErgoTree((ConstantSegregationHeader | ergoTreeHeaderInTests).toByte, constants, outExpr), + ErgoTree(setConstantSegregation(ergoTreeHeaderInTests), constants, outExpr), ErgoTree(ergoTreeHeaderInTests, EmptyConstants, prop) ) } @@ -173,7 +175,7 @@ class ErgoTreeSerializerSpecification extends SerializationSpecification forAll(samples) { (exp, hasDeserialize) => val t = new ErgoTree( - 16.toByte, + HeaderType @@ 16.toByte, Array(IntConstant(1)), Right(BoolToSigmaProp(EQ(ConstantPlaceholder(0, SInt), exp))) ) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala index 769bf25423..decc0ddc9f 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/AVLTreeScriptsSpecification.scala @@ -210,7 +210,7 @@ class AVLTreeScriptsSpecification extends CompilerTestingCommons ).asBoolValue.toSigmaProp prop shouldBe propExp - val newBox1 = testBox(10, pubkey, 0) + val newBox1 = testBox(10, ErgoTree.fromSigmaBoolean(pubkey), 0) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = createTransaction(newBoxes) @@ -258,7 +258,7 @@ class AVLTreeScriptsSpecification extends CompilerTestingCommons lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), - createTransaction(testBox(1, recipientProposition, 0)), + createTransaction(testBox(1, ErgoTree.fromSigmaBoolean(recipientProposition), 0)), self = selfBox, activatedVersionInTests) avlProver.performOneOperation(Lookup(treeElements.head._1)) @@ -326,7 +326,7 @@ class AVLTreeScriptsSpecification extends CompilerTestingCommons ).asBoolValue.toSigmaProp prop shouldBe propExp - val newBox1 = testBox(10, pubkey, 0) + val newBox1 = testBox(10, ErgoTree.fromSigmaBoolean(pubkey), 0) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = createTransaction(newBoxes) @@ -380,7 +380,7 @@ class AVLTreeScriptsSpecification extends CompilerTestingCommons val propTree = ErgoTree.fromProposition(ergoTreeHeaderInTests, prop) - val newBox1 = testBox(10, pubkey, 0) + val newBox1 = testBox(10, ErgoTree.fromSigmaBoolean(pubkey), 0) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = ErgoLikeTransaction(IndexedSeq(), newBoxes) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/DistributedSigSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/DistributedSigSpecification.scala index 9276413e1e..99fecd0aa1 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/DistributedSigSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/DistributedSigSpecification.scala @@ -1,7 +1,9 @@ package sigmastate.utxo +import sigmastate.Values.ErgoTree +import sigmastate.Values.ErgoTree.ZeroHeader import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeTestProvingInterpreter, CompilerTestingCommons} +import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeTestProvingInterpreter} import sigmastate.interpreter._ import sigmastate.lang.Terms._ @@ -518,7 +520,10 @@ class DistributedSigSpecification extends CompilerTestingCommons val sigAlice = proverA.signMessage(sigmaTree, msg, bagA).get - val bagB = proverB.bagForMultisig(ctx, sigmaTree, sigAlice, Seq(pubkeyAlice)) + val bagB = proverB.bagForMultisig(ctx, + ErgoTree.fromSigmaBoolean(ergoTreeHeaderInTests, sigmaTree), + proof = sigAlice, + realSecretsToExtract = Seq(pubkeyAlice)) .addHint(hintsFromBob.ownCommitments.head) val sigBob = proverB.signMessage(sigmaTree, msg, bagB).get diff --git a/sc/shared/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala b/sc/shared/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala index e9cf82616b..5353c906bd 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/blockchain/BlockchainSimulationTestingCommons.scala @@ -16,6 +16,7 @@ import scala.collection.mutable import scala.util.{Random, Try} import scorex.util._ import sigma.Colls +import sigmastate.Values.ErgoTree.ZeroHeader import sigmastate.interpreter.ContextExtension import sigmastate.interpreter.Interpreter.{ScriptNameProp, emptyEnv} import sigmastate.utxo.blockchain.BlockchainSimulationTestingCommons.{FullBlock, ValidationState} @@ -155,7 +156,7 @@ object BlockchainSimulationTestingCommons extends CompilerTestingCommons { val boxes = (1 to 50).map(_ => testBox(10, ErgoTree.fromProposition( - ErgoTree.headerWithVersion(scriptVersion), + ErgoTree.headerWithVersion(ZeroHeader, scriptVersion), Values.TrueLeaf.toSigmaProp), i, Seq(), Map(), txId)) createTransaction(boxes) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala index a9db5642cc..1b4ed1a8f1 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/CoinEmissionSpecification.scala @@ -168,7 +168,7 @@ block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661 height: Int): ErgoLikeTransaction = { assert(state.state.currentHeight == height - 1) val ut = if (emissionBox.value > s.oneEpochReduction) { - val minerBox = new ErgoBoxCandidate(emissionAtHeight(height), minerProp, height, Colls.emptyColl, Map()) + val minerBox = new ErgoBoxCandidate(emissionAtHeight(height), ErgoTree.fromSigmaBoolean(minerProp), height, Colls.emptyColl, Map()) val newEmissionBox: ErgoBoxCandidate = new ErgoBoxCandidate(emissionBox.value - minerBox.value, tree, height, Colls.emptyColl, Map(register -> IntConstant(height))) @@ -177,8 +177,8 @@ block 1600 in 1622 ms, 30000000000 coins remain, defs: 61661 IndexedSeq(newEmissionBox, minerBox) ) } else { - val minerBox1 = new ErgoBoxCandidate(emissionBox.value - 1, minerProp, height, Colls.emptyColl, Map(register -> IntConstant(height))) - val minerBox2 = new ErgoBoxCandidate(1, minerProp, height, Colls.emptyColl, Map(register -> IntConstant(height))) + val minerBox1 = new ErgoBoxCandidate(emissionBox.value - 1, ErgoTree.fromSigmaBoolean(minerProp), height, Colls.emptyColl, Map(register -> IntConstant(height))) + val minerBox2 = new ErgoBoxCandidate(1, ErgoTree.fromSigmaBoolean(minerProp), height, Colls.emptyColl, Map(register -> IntConstant(height))) UnsignedErgoLikeTransaction( IndexedSeq(new UnsignedInput(emissionBox.id)), IndexedSeq(minerBox1, minerBox2) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala index 1230177437..91e13fc4a1 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/ColdWalletAdvContractExampleSpecification.scala @@ -1,10 +1,10 @@ package sigmastate.utxo.examples -import org.ergoplatform.ErgoBox.{R6, R4, R5} +import org.ergoplatform.ErgoBox.{R4, R5, R6} import org.ergoplatform._ import sigmastate.{AvlTreeData, CompilerCrossVersionProps} -import sigmastate.Values.{LongConstant, IntConstant} -import sigmastate.helpers.{ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter, CompilerTestingCommons, ContextEnrichingTestProvingInterpreter} +import sigmastate.Values.{ErgoTree, IntConstant, LongConstant} +import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, ErgoLikeTestProvingInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ @@ -126,7 +126,7 @@ class ColdWalletAdvContractExampleSpecification extends CompilerTestingCommons R6 -> LongConstant(avbl2Key) // new avbl2Key (= old avbl2Key) ) ) - val firstWithdrawOutput1Key = testBox(firstWithdrawAmount1Key, carolPubKey, firstWithdrawHeight) + val firstWithdrawOutput1Key = testBox(firstWithdrawAmount1Key, ErgoTree.fromSigmaBoolean(carolPubKey), firstWithdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val firstWithdrawTx1Key = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(firstChangeOutput1Key, firstWithdrawOutput1Key)) @@ -163,7 +163,7 @@ class ColdWalletAdvContractExampleSpecification extends CompilerTestingCommons R6 -> LongConstant(avbl2Key - firstWithdrawAmount2Key) // new avbl2Key (= old avbl2Key) ) ) - val firstWithdrawOutput2Key = testBox(firstWithdrawAmount2Key, carolPubKey, firstWithdrawHeight) + val firstWithdrawOutput2Key = testBox(firstWithdrawAmount2Key, ErgoTree.fromSigmaBoolean(carolPubKey), firstWithdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val firstWithdrawTx2Key = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(firstChangeOutput2Key, firstWithdrawOutput2Key)) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala index ffd4b17018..868b67755a 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/ColdWalletContractExampleSpecification.scala @@ -2,10 +2,10 @@ package sigmastate.utxo.examples import org.ergoplatform.ErgoBox.{R4, R5} import org.ergoplatform._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, CompilerTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.{AvlTreeData, CompilerCrossVersionProps} -import sigmastate.Values.{LongConstant, IntConstant} +import sigmastate.Values.{ErgoTree, IntConstant, LongConstant} import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ @@ -92,7 +92,7 @@ class ColdWalletContractExampleSpecification extends CompilerTestingCommons // Both Alice ane Bob withdraw val withdrawAmountFull = depositAmount // full amount is withdrawn - val withdrawOutputAliceAndBob = testBox(withdrawAmountFull, carolPubKey, firstWithdrawHeight) + val withdrawOutputAliceAndBob = testBox(withdrawAmountFull, ErgoTree.fromSigmaBoolean(carolPubKey), firstWithdrawHeight) val withdrawTxAliceAndBob = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(withdrawOutputAliceAndBob)) @@ -122,7 +122,7 @@ class ColdWalletContractExampleSpecification extends CompilerTestingCommons R5 -> LongConstant(min) // newMin (= old min) = 99000 ) ) - val firstWithdrawOutput = testBox(firstWithdrawAmount, carolPubKey, firstWithdrawHeight) + val firstWithdrawOutput = testBox(firstWithdrawAmount, ErgoTree.fromSigmaBoolean(carolPubKey), firstWithdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val firstWithdrawTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(firstChangeOutput, firstWithdrawOutput)) @@ -152,7 +152,7 @@ class ColdWalletContractExampleSpecification extends CompilerTestingCommons R5 -> LongConstant(min) // newMin (= old min) ) ) - val withdrawOutputInvalid = testBox(withdrawAmountInvalid, carolPubKey, firstWithdrawHeight) + val withdrawOutputInvalid = testBox(withdrawAmountInvalid, ErgoTree.fromSigmaBoolean(carolPubKey), firstWithdrawHeight) // normally this transaction would be invalid, but we're not checking it in this test val withdrawTxInvalid = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(changeOutputInvalid, withdrawOutputInvalid)) @@ -187,7 +187,7 @@ class ColdWalletContractExampleSpecification extends CompilerTestingCommons R5 -> LongConstant(secondMin) // newMin ) ) - val secondWithdrawOutput = testBox(secondWithdrawAmount, carolPubKey, secondWithdrawHeight) + val secondWithdrawOutput = testBox(secondWithdrawAmount, ErgoTree.fromSigmaBoolean(carolPubKey), secondWithdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val secondWithdrawTx = ErgoLikeTransaction(IndexedSeq(), IndexedSeq(secondChangeOutput, secondWithdrawOutput)) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala index 44b69db572..a293e6b61a 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/CoopExampleSpecification.scala @@ -1,12 +1,13 @@ package sigmastate.utxo.examples -import org.ergoplatform.{ErgoLikeContext, ErgoLikeTransaction, ErgoBox} +import org.ergoplatform.{ErgoBox, ErgoLikeContext, ErgoLikeTransaction} import org.scalatest.Assertion import org.scalatest.TryValues._ -import sigmastate.crypto.DLogProtocol.{ProveDlog, DLogProverInput} +import sigmastate.crypto.DLogProtocol.{DLogProverInput, ProveDlog} import scorex.crypto.hash.Blake2b256 -import sigmastate.Values.{ByteArrayConstant, ErgoTree, BooleanConstant} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, CompilerTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.Values.ErgoTree.ZeroHeader +import sigmastate.Values.{BooleanConstant, ByteArrayConstant, ErgoTree} +import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.lang.Terms._ import sigmastate.{AvlTreeData, CompilerCrossVersionProps} @@ -65,7 +66,7 @@ class CoopExampleSpecification extends CompilerTestingCommons def pkWithTree(in: DLogProverInput): (ProveDlog, ErgoTree) = { val pk = in.publicImage - val tree = ErgoTree.fromSigmaBoolean(ErgoTree.headerWithVersion(0), pk) + val tree = ErgoTree.fromSigmaBoolean(ErgoTree.headerWithVersion(ZeroHeader, 0), pk) (pk, tree) } diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala index 15605481db..9fc84b37e7 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/MASTExampleSpecification.scala @@ -114,7 +114,7 @@ class MASTExampleSpecification extends CompilerTestingCommons lastBlockUtxoRoot = AvlTreeData.dummy, minerPubkey = ErgoLikeContextTesting.dummyPubkey, boxesToSpend = IndexedSeq(selfBox), - createTransaction(testBox(1, recipientProposition, 0)), + createTransaction(testBox(1, ErgoTree.fromSigmaBoolean(recipientProposition), 0)), self = selfBox, activatedVersionInTests) avlProver.performOneOperation(Lookup(knownSecretTreeKey)) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala index 6bbf410dc1..e697f15792 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/MixExampleSpecification.scala @@ -1,14 +1,13 @@ package sigmastate.utxo.examples import java.math.BigInteger - import org.ergoplatform.ErgoBox.{R4, R5} import scorex.crypto.hash.Blake2b256 import sigmastate.{AvlTreeData, CompilerCrossVersionProps} -import sigmastate.Values.GroupElementConstant +import sigmastate.Values.{ErgoTree, GroupElementConstant} import sigmastate.crypto.DLogProtocol.ProveDlog -import sigmastate.crypto.{DiffieHellmanTupleProverInput, ProveDHTuple, CryptoConstants} -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, CompilerTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.crypto.{CryptoConstants, DiffieHellmanTupleProverInput, ProveDHTuple} +import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ @@ -185,7 +184,7 @@ class MixExampleSpecification extends CompilerTestingCommons val carolPubKey: ProveDlog = carol.dlogSecrets.head.publicImage val spendHeight = 90 - val carolOutput = testBox(mixAmount, carolPubKey, spendHeight) + val carolOutput = testBox(mixAmount, ErgoTree.fromSigmaBoolean(carolPubKey), spendHeight) // normally this transaction would be invalid, but we're not checking it in this test val spendingTx = createTransaction(carolOutput) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala index eb76496c82..5339488473 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/OracleExamplesSpecification.scala @@ -104,7 +104,7 @@ class OracleExamplesSpecification extends CompilerTestingCommons val oracleBox = testBox( value = 1L, - ergoTree = oraclePubKey, + ergoTree = ErgoTree.fromSigmaBoolean(oraclePubKey), creationHeight = 0, additionalRegisters = Map( reg1 -> LongConstant(temperature), @@ -157,7 +157,7 @@ class OracleExamplesSpecification extends CompilerTestingCommons avlProver.performOneOperation(Lookup(ADKey @@@ oracleBox.id)) val proof = avlProver.generateProof() - val newBox1 = testBox(20, alicePubKey, 0, boxIndex = 2) + val newBox1 = testBox(20, ErgoTree.fromSigmaBoolean(alicePubKey), 0, boxIndex = 2) val newBoxes = IndexedSeq(newBox1) val spendingTransaction = createTransaction(newBoxes) @@ -251,8 +251,8 @@ class OracleExamplesSpecification extends CompilerTestingCommons ) val sOracle = oracleBox - val sAlice = testBox(10, prop, 0, Seq(), Map()) - val sBob = testBox(10, prop, 0, Seq(), Map()) + val sAlice = testBox(10, ErgoTree.fromProposition(prop), 0, Seq(), Map()) + val sBob = testBox(10, ErgoTree.fromProposition(prop), 0, Seq(), Map()) val newBox1 = testBox(20, mkTestErgoTree(alicePubKey), 0) val newBoxes = IndexedSeq(newBox1) @@ -266,8 +266,10 @@ class OracleExamplesSpecification extends CompilerTestingCommons spendingTransaction, self = sOracle, activatedVersionInTests) - val prA = alice.prove(emptyEnv + (ScriptNameProp -> "alice_prove"), prop, ctx, fakeMessage).get - verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), prop, ctx, prA, fakeMessage).get._1 shouldBe true + val prA = alice.prove(emptyEnv + (ScriptNameProp -> "alice_prove"), + mkTestErgoTree(prop), ctx, fakeMessage).get + verifier.verify(emptyEnv + (ScriptNameProp -> "verify"), + mkTestErgoTree(prop), ctx, prA, fakeMessage).get._1 shouldBe true } case class OracleContract[Spec <: ContractSpec] diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala index 1f00dbfc3c..05a2eb9c05 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/RPSGameExampleSpecification.scala @@ -4,10 +4,10 @@ package sigmastate.utxo.examples import org.ergoplatform.ErgoBox.{R4, R5, R6, R7} import scorex.crypto.hash.Blake2b256 import scorex.utils.Random -import sigmastate.Values.{ByteArrayConstant, ByteConstant, IntConstant, SigmaPropConstant} +import sigmastate.Values.{ByteArrayConstant, ByteConstant, ErgoTree, IntConstant, SigmaPropConstant} import sigmastate._ import sigmastate.crypto.DLogProtocol.ProveDlog -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, CompilerTestingCommons} +import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter._ import sigmastate.lang.Terms._ @@ -184,7 +184,7 @@ class RPSGameExampleSpecification extends CompilerTestingCommons val carolPubKey:ProveDlog = carol.dlogSecrets.head.publicImage // note that playAmount below is not checked. It could be anything. - val gameOverOutput = testBox(playAmount, carolPubKey, gameOverHeight) + val gameOverOutput = testBox(playAmount, ErgoTree.fromSigmaBoolean(carolPubKey), gameOverHeight) // normally this transaction would be invalid, but we're not checking it in this test val gameOverTx = createTransaction(gameOverOutput) @@ -273,7 +273,7 @@ class RPSGameExampleSpecification extends CompilerTestingCommons // assume Bob is paying to Carol // note that playAmount*2 below is not checked. It could be anything. - val defaultWinOutput = testBox(playAmount*2, carolPubKey, defaultWinHeight) + val defaultWinOutput = testBox(playAmount*2, ErgoTree.fromSigmaBoolean(carolPubKey), defaultWinHeight) //normally this transaction would invalid (why?), but we're not checking it in this test val defaultWinTx = createTransaction(defaultWinOutput) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala index f68c97079b..0a1987159c 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/ReversibleTxExampleSpecification.scala @@ -3,9 +3,9 @@ package sigmastate.utxo.examples import org.ergoplatform.ErgoBox.{R4, R5} import org.ergoplatform._ import scorex.crypto.hash.Blake2b256 -import sigmastate.Values.{IntConstant, SigmaPropConstant} +import sigmastate.Values.{ErgoTree, IntConstant, SigmaPropConstant} import sigmastate._ -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter, CompilerTestingCommons} +import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ @@ -174,7 +174,7 @@ class ReversibleTxExampleSpecification extends CompilerTestingCommons val bobSpendAmount = 10 val bobSpendHeight = bobDeadline+1 - val bobSpendOutput = testBox(bobSpendAmount, davePubKey, bobSpendHeight) + val bobSpendOutput = testBox(bobSpendAmount, ErgoTree.fromSigmaBoolean(davePubKey), bobSpendHeight) //normally this transaction would be invalid (why?), but we're not checking it in this test val bobSpendTx = createTransaction(bobSpendOutput) @@ -201,7 +201,7 @@ class ReversibleTxExampleSpecification extends CompilerTestingCommons val carolSpendHeight = bobDeadline - 1 // Carol sends to Dave - val carolSpendOutput = testBox(carolSpendAmount, davePubKey, carolSpendHeight) + val carolSpendOutput = testBox(carolSpendAmount, ErgoTree.fromSigmaBoolean(davePubKey), carolSpendHeight) //normally this transaction would be invalid (why?), but we're not checking it in this test val carolSpendTx = createTransaction(carolSpendOutput) diff --git a/sc/shared/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala b/sc/shared/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala index 04390272e8..3e94163532 100644 --- a/sc/shared/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala +++ b/sc/shared/src/test/scala/sigmastate/utxo/examples/TimedPaymentExampleSpecification.scala @@ -1,10 +1,10 @@ package sigmastate.utxo.examples import org.ergoplatform._ -import sigmastate.Values.IntConstant +import sigmastate.Values.{ErgoTree, IntConstant} import sigmastate._ import sigmastate.exceptions.InterpreterException -import sigmastate.helpers.{ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, CompilerTestingCommons, ErgoLikeTestInterpreter} +import sigmastate.helpers.{CompilerTestingCommons, ContextEnrichingTestProvingInterpreter, ErgoLikeContextTesting, ErgoLikeTestInterpreter} import sigmastate.helpers.TestingHelpers._ import sigmastate.interpreter.Interpreter.ScriptNameProp import sigmastate.lang.Terms._ @@ -53,7 +53,7 @@ class TimedPaymentExampleSpecification extends CompilerTestingCommons val withdrawHeight = 100 val confDeadline = 110 - val timedWithdrawOutput = testBox(withdrawAmount, bobPubKey, withdrawHeight) + val timedWithdrawOutput = testBox(withdrawAmount, ErgoTree.fromSigmaBoolean(bobPubKey), withdrawHeight) //normally this transaction would be invalid, but we're not checking it in this test val withdrawTx = createTransaction(IndexedSeq(timedWithdrawOutput)) diff --git a/sdk/shared/src/main/scala/org/ergoplatform/sdk/ContractTemplate.scala b/sdk/shared/src/main/scala/org/ergoplatform/sdk/ContractTemplate.scala index ac8da8f398..58b3a90101 100644 --- a/sdk/shared/src/main/scala/org/ergoplatform/sdk/ContractTemplate.scala +++ b/sdk/shared/src/main/scala/org/ergoplatform/sdk/ContractTemplate.scala @@ -9,8 +9,8 @@ import org.ergoplatform.sdk.utils.Zero import sigma.Evaluation import sigma.ast.SType import sigma.util.safeNewArray -import sigmastate.Values.ErgoTree.headerWithVersion -import sigmastate.Values.{ErgoTree, _} +import sigmastate.Values.ErgoTree.{ZeroHeader, headerWithVersion, setConstantSegregation} +import sigmastate.Values._ import sigmastate._ import sigmastate.eval._ import sigmastate.exceptions.SerializerException @@ -175,9 +175,9 @@ case class ContractTemplate( } } - val usedErgoTreeVersion = headerWithVersion(if (version.isDefined) version.get else treeVersion.get) + val usedErgoTreeHeader = headerWithVersion(ZeroHeader, if (version.isDefined) version.get else treeVersion.get) ErgoTree( - (ErgoTree.ConstantSegregationHeader | usedErgoTreeVersion).toByte, + setConstantSegregation(usedErgoTreeHeader), constants, this.expressionTree ) diff --git a/sdk/shared/src/main/scala/org/ergoplatform/sdk/utils/Zero.scala b/sdk/shared/src/main/scala/org/ergoplatform/sdk/utils/Zero.scala index 7b31553038..d8a0373ff9 100644 --- a/sdk/shared/src/main/scala/org/ergoplatform/sdk/utils/Zero.scala +++ b/sdk/shared/src/main/scala/org/ergoplatform/sdk/utils/Zero.scala @@ -11,6 +11,7 @@ import sigmastate.crypto.CryptoConstants import sigmastate.eval._ import sigmastate.{AvlTreeData, AvlTreeFlags, TrivialProp} import sigma._ +import sigmastate.Values.ErgoTree.HeaderType import java.math.BigInteger import scala.language.implicitConversions @@ -62,7 +63,7 @@ object Zero extends ZeroLowPriority { new ErgoBox( LongIsZero.zero, new ErgoTree( - ByteIsZero.zero, + HeaderType @@ ByteIsZero.zero, IndexedSeq.empty, Right(sigmaPropIsZero.zero) ), diff --git a/sdk/shared/src/test/scala/org/ergoplatform/sdk/ContractTemplateSpecification.scala b/sdk/shared/src/test/scala/org/ergoplatform/sdk/ContractTemplateSpecification.scala index 4bf866740a..44f2725a61 100644 --- a/sdk/shared/src/test/scala/org/ergoplatform/sdk/ContractTemplateSpecification.scala +++ b/sdk/shared/src/test/scala/org/ergoplatform/sdk/ContractTemplateSpecification.scala @@ -10,6 +10,7 @@ import sigmastate.serialization.{SerializationSpecification, SigmaSerializer} import sigma.ContractsTestkit import sigma.ast.{SByte, SInt, SType} import sigma.data.CBigInt +import sigmastate.Values.ErgoTree.setConstantSegregation import java.math.BigInteger @@ -205,13 +206,10 @@ class ContractTemplateSpecification extends SerializationSpecification Map("p1" -> IntConstant(10), "p2" -> IntConstant(20)), Map.empty[String, Constant[SType]] ) - var expectedErgoTreeVersion = (ErgoTree.ConstantSegregationHeader | ergoTreeVersionInTests).toByte - if (ergoTreeVersionInTests > 0) { - expectedErgoTreeVersion = (expectedErgoTreeVersion | ErgoTree.SizeFlag).toByte - } + val expectedErgoTreeHeader = setConstantSegregation(ergoTreeHeaderInTests) val expectedErgoTree = Seq( ErgoTree( - expectedErgoTreeVersion, + expectedErgoTreeHeader, IndexedSeq( ByteConstant(10.toByte), ByteConstant(40.toByte), @@ -220,7 +218,7 @@ class ContractTemplateSpecification extends SerializationSpecification expressionTrees(0) ), ErgoTree( - expectedErgoTreeVersion, + expectedErgoTreeHeader, IndexedSeq( IntConstant(10), IntConstant(20), @@ -229,7 +227,7 @@ class ContractTemplateSpecification extends SerializationSpecification expressionTrees(1) ), ErgoTree( - expectedErgoTreeVersion, + expectedErgoTreeHeader, Constant.EmptySeq, expressionTrees(2) ) @@ -256,12 +254,9 @@ class ContractTemplateSpecification extends SerializationSpecification ) val templateValues = Map("p1" -> IntConstant(10), "p2" -> IntConstant(30)) - var expectedErgoTreeVersion = (ErgoTree.ConstantSegregationHeader | ergoTreeVersionInTests).toByte - if (ergoTreeVersionInTests > 0) { - expectedErgoTreeVersion = (expectedErgoTreeVersion | ErgoTree.SizeFlag).toByte - } + val expectedErgoTreeHeader = setConstantSegregation(ergoTreeHeaderInTests) val expectedErgoTree = ErgoTree( - expectedErgoTreeVersion, + expectedErgoTreeHeader, IndexedSeq( IntConstant(10), IntConstant(20), diff --git a/sdk/shared/src/test/scala/org/ergoplatform/sdk/wallet/utils/Generators.scala b/sdk/shared/src/test/scala/org/ergoplatform/sdk/wallet/utils/Generators.scala index 3df10bf2ce..37c2c91c5f 100644 --- a/sdk/shared/src/test/scala/org/ergoplatform/sdk/wallet/utils/Generators.scala +++ b/sdk/shared/src/test/scala/org/ergoplatform/sdk/wallet/utils/Generators.scala @@ -100,7 +100,7 @@ trait Generators { Gen.choose(minValue, CoinsTotalTest / 1000) } - def ergoBoxGen(propGen: Gen[ErgoTree] = Gen.const(TrueLeaf.toSigmaProp), + def ergoBoxGen(propGen: Gen[ErgoTree] = Gen.const(ErgoTree.fromProposition(TrueLeaf.toSigmaProp)), tokensGen: Gen[Seq[Token]] = additionalTokensGen, valueGenOpt: Option[Gen[Long]] = None, heightGen: Gen[Int] = heightGen): Gen[ErgoBox] = for { @@ -144,10 +144,8 @@ trait Generators { } } - - def unsignedTxGen(secret: SecretKey): Gen[(IndexedSeq[ErgoBox], UnsignedErgoLikeTransaction)] = { - val dlog: Gen[ErgoTree] = Gen.const(secret.privateInput.publicImage.asInstanceOf[ProveDlog].toSigmaProp) + val dlog: Gen[ErgoTree] = Gen.const(ErgoTree.fromSigmaBoolean(secret.privateInput.publicImage.asInstanceOf[ProveDlog])) for { ins <- Gen.listOfN(2, ergoBoxGen(dlog))